Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Io\Poll: data buffered by the stream layer is not reported, and a stream closed while watched is never reported

Đang mở
#23,948 3 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
48/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
c, linux, php
Lĩnh vực
api, backend, operating-systems

Hướng nghiên cứu

Start by tracing Io\Poll Context::wait(), StreamPollHandle, and the Linux epoll backend, then reproduce both cases from the issue: buffered stream data and a watched stream closed during a wait. Done means wait() reports buffered reads and reports a watcher retired by close, with behavior comparable to stream_select().

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Category: IO Category: Streams
Description

@bukka — I've been writing a poller for phasync (a coroutine library) on top of Io\Poll, next to our stream_select() one, and ran our test suite against master. Two behaviours make a correct event loop hard to build on it, and both differ from stream_select():

1. Data already in the stream's read buffer isn't reported. After a read that buffered more than it returned (typical with fgets()), the socket is empty but the stream has unread data. stream_select() counts that stream as readable; Io\Poll only looks at the fd, so a loop that waits for readability before its next read never wakes.

use Io\Poll\{Context, Event};

[$a, $b] = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
fwrite($b, "first\nsecond\n");
fgets($a); // "first\n"; "second\n" is now in $a's read buffer, the socket is empty

$r = [$a]; $w = $e = null;
var_dump(stream_select($r, $w, $e, 0));   // int(1)

$poll = new Context();
$poll->add(new StreamPollHandle($a), [Event::Read]);
var_dump(count($poll->wait(Time\Duration::fromMilliseconds(100)))); // int(0)

We work around it by checking stream_get_meta_data($s)['unread_bytes'] before every wait, but every user of the API will hit this. Perhaps wait() could return the watchers of streams with buffered read data at once (as stream_select() does through stream_array_emulate_read_fd_set()), with Event::Read triggered.

2. A stream closed while watched is never reported. Since #23822, fclose() retires the watcher (which fixed the use-after-free), but wait() never tells the loop. A coroutine or callback waiting on that stream waits forever, unless the loop scans every watcher's isActive() periodically and caps its waits to do so:

use Io\Poll\{Context, Event};

[$a, $b] = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
$poll    = new Context();
$watcher = $poll->add(new StreamPollHandle($a), [Event::Read]);

fclose($a); // elsewhere in the program, while something waits on $a
var_dump($watcher->isActive());                                       // bool(false)
var_dump(count($poll->wait(Time\Duration::fromMilliseconds(100))));   // int(0): nobody is told

With stream_select() the next call throws on the closed stream (TypeError, or ValueError when it was the only one), so the loop can find and wake its waiter. Perhaps the next wait() could return a watcher retired by a close once, inactive, (e.g. with Event::HangUp triggered), so the loop wakes its waiter without scanning.

Let me know if you'd like me to write a PR for either.

PHP Version
PHP 8.7.0-dev (master)
Operating System

Linux (epoll backend)

Ngôn ngữ chính
C
Star
40.7k
Fork
8.3k
Merge trung bình
2 ngày 20 giờ
Pull request đã merge (30 ngày)
147

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của php/php-src

Tất cả issue của php/php-src

Issue tương tự

Thêm issue về C

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.