[PHP-DEV] [RFC] Polling API Additions

Hi,

I would like to introduce the Polling API Additions RFC:

https://wiki.php.net/rfc/poll_api_additions

This is follow up to Polling API RFC.

Kind regards,

Jakub

1 Like

On Wed, Sep 30, 2026, at 12:57 PM, Jakub Zelenka wrote:

Hi,

I would like to introduce the Polling API Additions RFC:

PHP: rfc:poll_api_additions

This is follow up to Polling API RFC.

Kind regards,

Jakub

While much of these two RFCs is over my head, I will reiterate the same point I made to Tim and Derick. You clearly have a roadmap in mind. The RFCs hint at that, and discuss some parts of it. But what's still missing is a single reference point with the full plan, at whatever level of granularity you have right now. Please please put something like that together, probably on the Wiki someplace that the RFCs can reference.

The work you're doing is incredibly important, and we really need to have a big picture view of the arc of your work so we can review it in the proper context.

--Larry Garfield

Am 30.09.2026 um 19:57 schrieb Jakub Zelenka:

I would like to introduce the Polling API Additions RFC:

PHP: rfc:poll_api_additions <PHP: rfc poll_api_additions>

Thank you for this RFC!

As far as I can tell, it is an amazing improvement. Watchers that cannot outlive their descriptor, signals and child process exits as events, and timers in the context make Io\Poll a complete foundation for an event loop, without PECL extensions or userland workarounds.

I would echo Larry's request for the big picture. The RFCs hint at a roadmap, and a single wiki page outlining the full plan, at whatever level of detail exists today, that the RFCs could reference would help a lot.

Best,
Sebastian

--
Sebastian Bergmann https://phpunit.expert

Stay up to date with PHPUnit: https://phpunit.expert/newsletter

Hi,

On Thu, Oct 1, 2026 at 3:30 PM Larry Garfield <larry@garfieldtech.com> wrote:

On Wed, Sep 30, 2026, at 12:57 PM, Jakub Zelenka wrote:

Hi,

I would like to introduce the Polling API Additions RFC:

https://wiki.php.net/rfc/poll_api_additions

This is follow up to Polling API RFC.

Kind regards,

Jakub

While much of these two RFCs is over my head, I will reiterate the same point I made to Tim and Derick. You clearly have a roadmap in mind. The RFCs hint at that, and discuss some parts of it. But what’s still missing is a single reference point with the full plan, at whatever level of granularity you have right now. Please please put something like that together, probably on the Wiki someplace that the RFCs can reference.

The work you’re doing is incredibly important, and we really need to have a big picture view of the arc of your work so we can review it in the proper context.

If you are asking about a complete and detailed design doc for all 3 RFC’s, it can be found at https://gist.github.com/bukka/87359261a4bfaa572ce43c93c0554b55 (I just added a link to the RFC’s).

There is really no roadmap except what is in those 3 RFC’s (and more details in that document). This particular RFC builds on existing Polling API and introduces all bits that are needed to make it usable with IO Hooks introduced in another RFC. The hooks RFC is all that is needed to allow introduction of IO suspension points. The Ring RFC completes it with option for IO offloading. There can be future implementation like Edmond’s scheduler that could make full use of this for the IO side of things. The API was developed with this in mind but essentially it’s an independent project. The polling API additions are useful even without the IO Hooks as those features are already requested by user space users of the API. If you feel that some more details should be added to IO Hooks, please comment there with a bit more specific info what exactly would you like to see there.

Kind regards,

Jakub

Hi Jakub,

Timers, notify and priority look good to me, and the deadline heap and
WNOWAIT choices are the right ones. A few things from reading and
running the io_hooks_poc branch before a vote:

  1. Please split the vote by group. Signals carry most of the risk and
    shouldn’t hold back timers.

  2. exec(), system(), passthru(), shell_exec() and backticks go through
    libc popen() and never reset the mask. With /bin/sh as bash the
    child gets SIGTERM blocked; with dash only exec-prefixed commands
    do. “The blocked mask does not leak into executed programs” needs a
    single choke point, not a list of call sites.

  3. pcntl can unblock a watched signal behind the handle:
    pcntl_sigprocmask(SIG_UNBLOCK/SIG_SETMASK) directly, and
    pcntl_signal() via zend_sigaction(), which unblocks the signal it
    installs. In both cases the pcntl handler runs and the handle sees
    nothing, so “a handler installed with pcntl_signal() never runs
    while a handle for it is watched” doesn’t hold with zend signals on.

  4. While SIGTERM is watched, sleep() and blocking reads run to
    completion, and a script that never calls wait() exits 0: the
    shutdown drain records the signal into a handle that is then freed.
    Worth stating, and it’s the main argument for the self-pipe model
    in your open issue.

  5. onWatcherRemoved also fires for the script’s own fclose() (your
    poll_weakhandle_on_watcher_removed.phpt relies on it), so the
    connection-table example comment is wrong.

  6. The PoC changes wait() on EINTR from throwing FailedPollWaitException
    to restarting or returning . I think that’s right, but it changes
    the 8.6 API and should be in the RFC. A signal landing in wait()
    before the syscall still blocks it with the PHP handler pending; a
    php_io_interrupt_pending() check before blocking would close that.

  7. ProcessHandle: new ProcessHandle($pid) for a non-child races pid
    reuse, and the exit probe uses waitid(P_PID) rather than P_PIDFD, so
    after an external reap it can read another process’s status.
    getStatus() is a wait status on POSIX and an exit code on Windows,
    and non-null for non-children only on Windows.

  8. TimerHandle: please specify the clock and that the deadline starts
    at add(), which is what the PoC does with zend_hrtime().

  9. isExposed() and the in-use null from getStream() can’t be observed
    through this RFC’s API alone; they belong with IO hooks.

···

Ilia Alshanetsky
Technologist, CTO, Entrepreneur
E: ilia@ilia.ws
T: @iliaa
B: http://ilia.ws