Skip to content

Report Io\Poll level watchers with buffered stream data - #24017

Merged
bukka merged 1 commit into
php:PHP-8.6from
bukka:poll_buffered_data
Nov 1, 2026
Merged

bukka merged 1 commit into
php:PHP-8.6from
bukka:poll_buffered_data

Conversation

@bukka

@bukka bukka commented Sep 30, 2026

Copy link
Copy Markdown
Member

A stream can hold unread data in its buffer while its descriptor is idle. stream_select() treats such a stream as readable but a level watcher looked at the descriptor only, so a loop waiting for readability never woke up (GH-23948).

Context::wait() now checks level watchers with Read interest for buffered data first and reports them with Read triggered. The backend is then asked without waiting so descriptor events are merged in and a watcher readable both ways is returned once. Edge watchers are not affected. A one-shot reported from its buffer is disarmed like one fired by the backend and modifyEvents() re-arms it. The check reads the stream buffer positions only and does no IO.

The check is a handle operation so other handle types can provide it. It is registered separately as php_poll_handle_ext_ops because the handle ops struct cannot grow without an ABI change. This is temporary and the operation moves to the ops struct in master.

Comment thread main/php_poll.h Resolved
Comment thread ext/standard/io_poll.c Resolved
A stream can hold unread data in its buffer while its descriptor is idle.
stream_select() treats such a stream as readable but a level watcher
looked at the descriptor only, so a loop waiting for readability never
woke up (phpGH-23948).

Context::wait() now checks level watchers with Read interest for buffered
data first and reports them with Read triggered. The backend is then asked
without waiting so descriptor events are merged in and a watcher readable
both ways is returned once. Edge watchers are not affected. A one-shot
reported from its buffer is disarmed like one fired by the backend and
modifyEvents() re-arms it. The check reads the stream buffer positions
only and does no IO.

The check is a handle operation so other handle types can provide it. It
is registered separately as php_poll_handle_ext_ops because the handle ops
struct cannot grow without an ABI change. This is temporary and the
operation moves to the ops struct in master.
@bukka
bukka force-pushed the poll_buffered_data branch from a96a61f to aeba1ac Compare November 1, 2026 18:26
@bukka
bukka merged commit 954f796 into php:PHP-8.6 Nov 1, 2026
17 of 18 checks passed
bukka added a commit that referenced this pull request Nov 1, 2026
* PHP-8.6:
  Report Io\Poll level watchers with buffered stream data (#24017)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants