Repository navigation
fix: keep Go's preemption signal off the PHP threads - #2833
Open
nicolas-grekas wants to merge 1 commit into
Open
nicolas-grekas wants to merge 1 commit into
nicolas-grekas wants to merge 1 commit into
Conversation
The Go runtime preempts goroutines with SIGURG, sent to the thread that runs them. A PHP thread runs Go code during each callback, and the signal may only land once the thread is back in PHP and entering a system call, which then fails with EINTR: stream_select() returns false with a warning, a poll context throws. Blocking the signal when the thread starts does not hold, Go unblocks it at the first call into Go. Blocked after that call, it stays blocked, since the thread keeps its M.
henderkes
approved these changes
Nov 12, 2026
henderkes
left a comment
Contributor
There was a problem hiding this comment.
I'm starting to understand why everyone hates Cgo. I wish there was a long-term solution to all these Go runtime things without kicking the project into manual go library build mode.
dunglas
approved these changes
Nov 12, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Go runtime preempts goroutines with
SIGURG, sent to the thread that runs them. A PHP thread runs Go code during each callback, and the signal may only land once the thread is back in PHP and entering a system call, which then fails withEINTR:stream_select()returnsfalsewith a warning,Io\Poll\Context::wait()throws aFailedPollWaitException.I get one interrupted wait in 240k when a script follows tasks through a poll context (#2636), and none with
GODEBUG=asyncpreemptoff=1.Blocking the signal when the thread starts doesn't hold: Go unblocks it at the first call into Go. Blocked after that call, it stays blocked, since the thread keeps its M. The Go code of a PHP thread is then preempted at its safe points only, which its callbacks reach quickly.