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
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.
--Larry Garfield
Hi,
On Thu, Oct 1, 2026 at 3:30 PM Larry Garfield larry@garfieldtech.com
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
Am 30.09.2026 um 19:57 schrieb Jakub Zelenka:
I would like to introduce the Polling API Additions RFC:
https://wiki.php.net/rfc/poll_api_additions <https://wiki.php.net/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
I would like to introduce the Polling API Additions RFC:
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:
-
Please split the vote by group. Signals carry most of the risk and
shouldn't hold back timers. -
exec(),system(),passthru(),shell_exec()and backticks go through
libcpopen()and never reset the mask. With /bin/sh as bash the
child getsSIGTERMblocked; 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. -
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 withpcntl_signal()never runs
while a handle for it is watched" doesn't hold with zend signals on. -
While
SIGTERMis 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. -
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. -
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. -
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. -
TimerHandle: please specify the clock and that the deadline starts
at add(), which is what the PoC does with zend_hrtime(). -
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
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.
Thank you for your RFC. As I already mentioned off-list I'm very much
looking forward to the next parts of the polling API.
I've given the RFC a full read now and have the following comments, many
of which are questions intended to spark a discussion, instead of
concrete fully-refined suggestions.
-
I agree with Ilia's suggestion to split the RFC into multiple scoped
votes, even if everything is discussed at the same time for the “big
picture”. The RFC itself already mentions “Every addition is useful on
its own” in the introduction. This also allows to easily split off the
parts that might need just a little more discussion. The “URI followup”
for PHP 8.6 would be a good example. It started with 6 things, two were
split off and the remaining 4 had a separate (primary) vote each. -
Is the separate
WeakHandleinterface and classes necessary? Would
it also be possible to do something likenew StreamPollHandle(WeakReference::create($stream))? It would be
unfortunate if it would be necessary to duplicate everything as “strong”
and “weak”. -
Can the RFC document the expected
callablesignature for
Context::onWatcherRemoved()(e.g. is the callback: void, what
parameters are passed to it?). -
I'm not sure about the naming and namespacing of the
TimerHandle.
Putting it straight intoIo\Pollwould make the namespace very full.
For Random\Engine and the currently discussed Time\Clock we put the
implementations of the interface in a sub-namespace named after the
interface (and dropped theHandlesuffix). In contrast to
StreamPollHandle, theHandlesuffix onTimerHandledoesn't carry
any additional meaning and I don't think it helps disambiguation when
imported in an unqualified way. Not sure ifIo\Poll\Handle\Timeris
the correct choice. Perhaps it can also be justIo\Timerwhen the
Timeris usable standalone, e.g. using aIo\Timer::sleep()method or
similar - or it would be correctly placed inTime\similarly to
Golang.
Even though I'm not 100% convinced by my suggestion, I wanted to put it
out to allow discussing it. Perhaps someone else on this list has a good
suggestion or reasoning based on my rough idea.
-
The RFC should explain if
getTimeout()returns the constructor
parameter directly - or if it returns the remaining timeout. -
Would having a
TimerHandle::pause()orTimerHandle::stop()or
TimerHandle::reset()method be useful to allow modifying the timer
without going through the Context? -
As an aside: I'm happy that we could immediately find another use for
Durationwith theTimerHandle. This is a good indication for me that
it was worth it getting it into 8.6 last minute to ensure a nice and
consistent polling API :-) -
For
TimerHandle: Should the configured timeout and the periodic
flag be exposed as (readonly) properties instead of methods? Those are
effectively “properties” of the object in the English sense of the word. -
Similarly to
TimerHandlealso for theSignalHandle: Would it
theoretically be possible for theSignalHandleto act both as a
standalone API and be usable with the polling API? Not sure if that
makes sense. Is there perhaps precedent in other programming languages? -
For
ProcessHandleI don't think we should have both a regular
constructor and named constructor. This makes discoverability worse,
because the regular constructor doesn't show up in autocompletion for
ProcessHandle::from*. -
It is not unlikely that we want to introduce a new “Process” API to
improve developer experience. Tying theProcessHandleclass to the
existingproc_open()resources would be unfortunate when a new API
with new concepts is then introduced. It will also not show up when
autocompletingproc_*(). My suggestion would therefore be a
proc_get_poll_handle()function ot similar that constructs the
ProcessHandle, while keeping the integration contained in the
`proc_*()' API. -
For the
NotifyHandle: Is it possible or does it make sense for it
to support providing additional “metadata” as part of the notification,
such as->notify("hey, wake up"), similarly to how theProcessHandle
provides the exit status. -
The “RFC Impact” section is following an old template, and the
ecosystem impact subsection is missing. Could you add some short note
about the expected Impact for e.g. ReactPHP? -
In the “RFC Impact” section the RFC says “SignalHandle is limited to
the CLI SAPI in thread-safe builds”, which is ambiguous to me. Is this
“SignalHandle only works in ZTS CLI. It does not work in NTS at all and
does not work in ZTS FPM / FrankenPHP” or is this “SignalHandle works in
all NTS. For ZTS only CLI is supported”? Based on the explanation of the
SignalHandle, I assume it's the latter? -
Seeing the examples: Can you clarify the behavior of
SignalHandle::getDelivered(). Which previous call is meant? Is it the
previous call toSignalHandle::getDelivered()or is it the previous
call toContext::wait()? Would it make sense to make
SignalHandle::getDelivered()return a generator instead to make it
more explicit that the return value is only meant to be consumed once?
Best regards
Tim Düsterhus