Merge branch 'PHP-8.2'

* PHP-8.2:
  [ci skip] NEWS
  [ci skip] NEWS
  fix: support for timeouts with ZTS on Linux (#10141)
This commit is contained in:
Arnaud Le Blanc 2023-03-03 11:56:34 +01:00
commit 0c7fc351ea
11 changed files with 253 additions and 1 deletions

View file

@ -44,6 +44,9 @@
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef ZEND_MAX_EXECUTION_TIMERS
#include <sys/syscall.h>
#endif
ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data);
ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data, zval *return_value);
@ -196,6 +199,7 @@ void init_executor(void) /* {{{ */
EG(filename_override) = NULL;
EG(lineno_override) = -1;
zend_max_execution_timer_init();
zend_fiber_init();
zend_weakrefs_init();
@ -413,6 +417,7 @@ void shutdown_executor(void) /* {{{ */
zend_shutdown_executor_values(fast_shutdown);
zend_weakrefs_shutdown();
zend_max_execution_timer_shutdown();
zend_fiber_shutdown();
zend_try {
@ -1367,8 +1372,35 @@ ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void) /* {{{ */
/* }}} */
#ifndef ZEND_WIN32
# ifdef ZEND_MAX_EXECUTION_TIMERS
static void zend_timeout_handler(int dummy, siginfo_t *si, void *uc) /* {{{ */
{
#ifdef ZTS
if (!tsrm_is_managed_thread()) {
fprintf(stderr, "zend_timeout_handler() called in a thread not managed by PHP. The expected signal handler will not be called. This is probably a bug.\n");
return;
}
#endif
if (si->si_value.sival_ptr != &EG(max_execution_timer_timer)) {
#ifdef MAX_EXECUTION_TIMERS_DEBUG
fprintf(stderr, "Executing previous handler (if set) for unexpected signal SIGRTMIN received on thread %d\n", (pid_t) syscall(SYS_gettid));
#endif
if (EG(oldact).sa_sigaction) {
EG(oldact).sa_sigaction(dummy, si, uc);
return;
}
if (EG(oldact).sa_handler) EG(oldact).sa_handler(dummy);
return;
}
# else
static void zend_timeout_handler(int dummy) /* {{{ */
{
# endif
#ifdef ZTS
if (!tsrm_is_managed_thread()) {
fprintf(stderr, "zend_timeout_handler() called in a thread not managed by PHP. The expected signal handler will not be called. This is probably a bug.\n");
@ -1474,6 +1506,21 @@ static void zend_set_timeout_ex(zend_long seconds, bool reset_signals) /* {{{ */
zend_error_noreturn(E_ERROR, "Could not queue new timer");
return;
}
#elif defined(ZEND_MAX_EXECUTION_TIMERS)
zend_max_execution_timer_settime(seconds);
if (reset_signals) {
sigset_t sigset;
struct sigaction act;
act.sa_sigaction = zend_timeout_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_ONSTACK | SA_SIGINFO;
sigaction(SIGRTMIN, &act, NULL);
sigemptyset(&sigset);
sigaddset(&sigset, SIGRTMIN);
sigprocmask(SIG_UNBLOCK, &sigset, NULL);
}
#elif defined(HAVE_SETITIMER)
{
struct itimerval t_r; /* timeout requested */
@ -1539,6 +1586,8 @@ void zend_unset_timeout(void) /* {{{ */
}
tq_timer = NULL;
}
#elif ZEND_MAX_EXECUTION_TIMERS
zend_max_execution_timer_settime(0);
#elif defined(HAVE_SETITIMER)
if (EG(timeout_seconds)) {
struct itimerval no_timeout;