-
Notifications
You must be signed in to change notification settings - Fork 7.8k
fix: support for timeouts with ZTS on Linux #10141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
78d13eb
to
ca660b6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The choice of SIGIO
seems reasonable based on the mentioned heuristics. The fact that the handler is able to ignore SIGIOs that was not caused by this specific timer is a good thing too (can we fallback to a previously set handler in this case?).
The first heuristic (being passed-through by debuggers) is much less relevant for this use-case than for Go's use-case - does it makes new choices available if we ignore this heuristic?
It could we worth it to comment about the reasons that led to SIGIO, so that we don't revert to SIGURG or SIGPROF in the future.
I'm not sure how (and if it's necessary) to write a test for this in PHP. I could add an ad-hoc C program doing something similar as in FrankenPHP's test, WDYT?
If the required effort is moderate, it would be worth it. You could add a function in ext/zend_test to execute a script in a separate thread.
Pinging @morrisonlevi @tstarling who showed interest
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept reviewed, looks like it should work. Needs a line-by-line close review but that can happen after some cleanups are done.
If we want debuggers to handle the timeout signal, maybe could we also use |
6805b90
to
18ffe66
Compare
@arnaud-lb @tstarling the patch is ready for another round of reviews, if you don't mind. I'm not fond of this: Lines 90 to 95 in 6feb7cd
I would prefer throwing an error, but if I do, I'm trying to reproduce the FPM errors, but it's most likely related to the calls to |
bbea10d
to
7761962
Compare
Tests are now green and the code looks good to me. Could you look if the last version of this patch is ok for you? I'm hesitating on the naming: "Zend Timer" or "Zend Timers"? |
FYI, I will take a look at this tomorrow. I think the plural "Zend Timers" is better, personally. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't ran the code yet, this review is just from reading through it. I plan to check out the branch later today to test it under Apache Event MPM.
@morrisonlevi it looks like this MPM uses both |
What part of the Edit: Ah, found it here: https://heap.space/xref/php-src/sapi/apache2handler/sapi_apache2.c?r=aef7d810#758. |
58a0a04
to
7ac86b6
Compare
My tests with Apache Event MPM were successful. @morrisonlevi @arnaud-lb would you mind reviewing again? Thanks! |
This looks good to me, but it's unfortunate that we have to handle forks.
If we store the process id at the same time we initialize
|
7ac86b6
to
c0bef12
Compare
e79e9ff
to
fdcd57e
Compare
Thank you! |
* PHP-8.1: [ci skip] NEWS fix: support for timeouts with ZTS on Linux (#10141)
* PHP-8.2: [ci skip] NEWS [ci skip] NEWS fix: support for timeouts with ZTS on Linux (#10141)
Thanks for your work on this! |
In configure.ac check for function strerror_r defines constant HAVE_STRERROR_R.
In configure.ac check for function strerror_r defines constant HAVE_STRERROR_R.
This is undocumented or not? |
Closes https://bugs.php.net/bug.php?id=79464, #9738 and golang/go#56260.
Follows the plan described in this mail: https://externals.io/message/118859.
Currently, timeouts don't work at all on ZTS builds because signals are emitted by
setitimer()
, which is per-process. This patch fixes the problem on Linux by usingtimer_create()
withSIGEV_THREAD_ID
, as suggested by @nikic.Also, this patch uses
SIGIO
instead ofSIGPROF
to prevent messing with profilers. This also improves the compatibility of PHP with Go (which is important for FrankenPHP). Why hijackSIGIO
? Because there is no good way to choose this signal, andSIGIO
is probably the safest signal in our case (SIGURG
is already used internally by Go for its non-cooperative preemption feature).This fix only works for Linux because Mac and BSD don't implement
timer_create()
. It may be possible to use libdispatch on Mac and FreeBSD to achieve something similar, but it's out of scope for this patch.It's safe to merge this in 8.1 because the new system is only enabled for Linux ZTS builds, and timeouts are currently totally broken for this platform.
I wrote a test in FrankenPHP proving that this patch fixes the problem: dunglas/frankenphp#128
I'm not sure how (and if it's necessary) to write a test for this in PHP. I could add an ad-hoc C program doing something similar as in FrankenPHP's test, WDYT?
TODO:
./configure
argument to enable or disable Zend Timers