On Wed, Sep 30, 2026 at 2:00 PM Jakub Zelenka <[email protected]> wrote:
> I would like to introduce the Polling API Additions RFC: > > https://wiki.php.net/rfc/poll_api_additions > 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: [email protected] T: @iliaa B: http://ilia.ws
