From 2afb398e42f1ef1b75a2dd989448cad1fab25247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 22 Feb 2024 00:44:02 +0100 Subject: [PATCH 1/8] feat: macOS support for Zend Max Execution timers --- Zend/Zend.m4 | 24 ++++-- Zend/zend_execute_API.c | 7 +- Zend/zend_globals.h | 8 ++ Zend/zend_max_execution_timer.c | 133 +++++++++++++++++++++++++++----- Zend/zend_max_execution_timer.h | 6 ++ 5 files changed, 149 insertions(+), 29 deletions(-) diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index 47e79f77dc2cb..6750c62a20599 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -304,12 +304,24 @@ AC_ARG_ENABLE([zend-max-execution-timers], [ZEND_MAX_EXECUTION_TIMERS=$enableval], [ZEND_MAX_EXECUTION_TIMERS=$ZEND_ZTS]) -AS_CASE(["$host_alias"], [*linux*|*freebsd*], [], [ZEND_MAX_EXECUTION_TIMERS='no']) - -PHP_CHECK_FUNC(timer_create, rt) -if test "$ac_cv_func_timer_create" != "yes"; then - ZEND_MAX_EXECUTION_TIMERS='no' -fi +AS_CASE( + ["$host_alias"], + [*linux*|*freebsd*], [ + PHP_CHECK_FUNC(timer_create, rt) + if test "$ac_cv_func_timer_create" != "yes"; then + ZEND_MAX_EXECUTION_TIMERS='no' + fi + ], + [*darwin*], [], + [ZEND_MAX_EXECUTION_TIMERS='no'] +) + +AS_CASE(["$host_alias"], [*darwin*], [], [ + PHP_CHECK_FUNC(timer_create, rt) + if test "$ac_cv_func_timer_create" != "yes"; then + ZEND_MAX_EXECUTION_TIMERS='no' + fi +]) if test "$ZEND_MAX_EXECUTION_TIMERS" = "yes"; then AC_DEFINE(ZEND_MAX_EXECUTION_TIMERS, 1, [Use zend max execution timers]) diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index c297523b9249a..0aa126e35b3f9 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1411,6 +1411,7 @@ static void zend_timeout_handler(int dummy, siginfo_t *si, void *uc) /* {{{ */ } #endif +#ifndef __APPLE__ 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)); @@ -1425,6 +1426,7 @@ static void zend_timeout_handler(int dummy, siginfo_t *si, void *uc) /* {{{ */ return; } +#endif # else static void zend_timeout_handler(int dummy) /* {{{ */ { @@ -1544,9 +1546,10 @@ static void zend_set_timeout_ex(zend_long seconds, bool reset_signals) /* {{{ */ act.sa_sigaction = zend_timeout_handler; sigemptyset(&act.sa_mask); act.sa_flags = SA_ONSTACK | SA_SIGINFO; - sigaction(SIGRTMIN, &act, NULL); + sigaction(ZEND_MAX_EXECUTION_TIMERS_SIGNAL, &act, NULL); + sigemptyset(&sigset); - sigaddset(&sigset, SIGRTMIN); + sigaddset(&sigset, ZEND_MAX_EXECUTION_TIMERS_SIGNAL); sigprocmask(SIG_UNBLOCK, &sigset, NULL); } #elif defined(HAVE_SETITIMER) diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 8900a5f416f53..ff6d8d0bd9d50 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -24,6 +24,9 @@ #include #include #include +#ifdef __APPLE__ +#include +#endif #include "zend_globals_macros.h" @@ -299,7 +302,12 @@ struct _zend_executor_globals { #endif #ifdef ZEND_MAX_EXECUTION_TIMERS +# ifdef __APPLE__ + dispatch_source_t max_execution_timer_timer; + bool max_execution_timer_suspended; +# else timer_t max_execution_timer_timer; +# endif pid_t pid; struct sigaction oldact; #endif diff --git a/Zend/zend_max_execution_timer.c b/Zend/zend_max_execution_timer.c index 16c2b7e2b8d23..f36e35ce0dc31 100644 --- a/Zend/zend_max_execution_timer.c +++ b/Zend/zend_max_execution_timer.c @@ -16,6 +16,96 @@ #ifdef ZEND_MAX_EXECUTION_TIMERS +# ifdef __APPLE__ + +#include +# ifdef ZTS +#include +# endif + +#include "zend.h" +#include "zend_globals.h" + +// macOS doesn't support timer_create(), fallback to Grand Central Dispatch + +static inline void zend_max_execution_timer_handler(void *arg) +{ + pthread_t *tid = (pthread_t *) arg; + pthread_kill(*tid, ZEND_MAX_EXECUTION_TIMERS_SIGNAL); +} + +static inline void zend_max_execution_timer_cancel(void *arg) +{ + pthread_t *tid = (pthread_t *) arg; + free(tid); +} + +ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ +{ + pid_t pid = getpid(); + + if (EG(pid) == pid) { + return; + } + + dispatch_queue_global_t queue = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0); + EG(max_execution_timer_timer) = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); + if (EG(max_execution_timer_timer) == NULL) { + zend_strerror_noreturn(E_ERROR, errno, "Could not create dispatch source"); + } + + EG(pid) = pid; + EG(max_execution_timer_suspended) = 1; + +# ifdef ZTS + pthread_t lpid = pthread_self(); + pthread_t *tid = malloc(sizeof(pthread_t)); + memcpy(tid, &lpid, sizeof(pthread_t)); + dispatch_set_context(EG(max_execution_timer_timer), tid); +# endif + + dispatch_source_set_event_handler_f(EG(max_execution_timer_timer), zend_max_execution_timer_handler); + dispatch_source_set_cancel_handler_f(EG(max_execution_timer_timer), zend_max_execution_timer_cancel); +} /* }}} */ + +void zend_max_execution_timer_settime(zend_long seconds) /* {{{ */ +{ + if (seconds == 0) { + if (!EG(max_execution_timer_suspended)) { + dispatch_suspend(EG(max_execution_timer_timer)); + EG(max_execution_timer_suspended) = 1; + } + + return; + } + + dispatch_source_set_timer( + EG(max_execution_timer_timer), + dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC), + seconds * NSEC_PER_SEC, + 0 + ); + if (EG(max_execution_timer_suspended)) { + dispatch_resume(EG(max_execution_timer_timer)); + EG(max_execution_timer_suspended) = 0; + } +} /* }}} */ + +void zend_max_execution_timer_shutdown(void) /* {{{ */ +{ + /* Don't try to delete a timer created before a call to fork() */ + if (EG(pid) != getpid()) { + return; + } + + EG(pid) = 0; + + dispatch_source_cancel(EG(max_execution_timer_timer)); + //dispatch_release(EG(max_execution_timer_timer)); +} /* }}} */ + +# else + #include #include #include @@ -23,25 +113,25 @@ #include #include #include -# ifdef __FreeBSD__ -# include -# endif +# ifdef __FreeBSD__ +# include +# endif #include "zend.h" #include "zend_globals.h" // Musl Libc defines this macro, glibc does not // According to "man 2 timer_create" this field should always be available, but it's not: https://sourceware.org/bugzilla/show_bug.cgi?id=27417 -# ifndef sigev_notify_thread_id -# define sigev_notify_thread_id _sigev_un._tid -# endif +# ifndef sigev_notify_thread_id +# define sigev_notify_thread_id _sigev_un._tid +# endif // FreeBSD doesn't support CLOCK_BOOTTIME -# ifdef __FreeBSD__ -# define ZEND_MAX_EXECUTION_TIMERS_CLOCK CLOCK_MONOTONIC -# else -# define ZEND_MAX_EXECUTION_TIMERS_CLOCK CLOCK_BOOTTIME -# endif +# ifdef __FreeBSD__ +# define ZEND_MAX_EXECUTION_TIMERS_CLOCK CLOCK_MONOTONIC +# else +# define ZEND_MAX_EXECUTION_TIMERS_CLOCK CLOCK_BOOTTIME +# endif ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ { @@ -54,12 +144,12 @@ ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ struct sigevent sev; sev.sigev_notify = SIGEV_THREAD_ID; sev.sigev_value.sival_ptr = &EG(max_execution_timer_timer); - sev.sigev_signo = SIGRTMIN; -# ifdef __FreeBSD__ + sev.sigev_signo = ZEND_MAX_EXECUTION_TIMERS_SIGNAL; +# ifdef __FreeBSD__ sev.sigev_notify_thread_id = pthread_getthreadid_np(); -# else +# else sev.sigev_notify_thread_id = (pid_t) syscall(SYS_gettid); -# endif +# endif // Measure wall time instead of CPU time as originally planned now that it is possible https://github.com/php/php-src/pull/6504#issuecomment-1370303727 if (timer_create(ZEND_MAX_EXECUTION_TIMERS_CLOCK, &sev, &EG(max_execution_timer_timer)) != 0) { @@ -68,9 +158,9 @@ ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ EG(pid) = pid; -# ifdef MAX_EXECUTION_TIMERS_DEBUG +# ifdef MAX_EXECUTION_TIMERS_DEBUG fprintf(stderr, "Timer %#jx created on thread %d\n", (uintmax_t) EG(max_execution_timer_timer), sev.sigev_notify_thread_id); -# endif +# endif sigaction(sev.sigev_signo, NULL, &EG(oldact)); } @@ -89,9 +179,9 @@ void zend_max_execution_timer_settime(zend_long seconds) /* {{{ }*/ its.it_value.tv_sec = seconds; its.it_value.tv_nsec = its.it_interval.tv_sec = its.it_interval.tv_nsec = 0; -# ifdef MAX_EXECUTION_TIMERS_DEBUG +# ifdef MAX_EXECUTION_TIMERS_DEBUG fprintf(stderr, "Setting timer %#jx on thread %d (%ld seconds)...\n", (uintmax_t) timer, (pid_t) syscall(SYS_gettid), seconds); -# endif +# endif if (timer_settime(timer, 0, &its, NULL) != 0) { zend_strerror_noreturn(E_ERROR, errno, "Could not set timer"); @@ -110,9 +200,9 @@ void zend_max_execution_timer_shutdown(void) /* {{{ */ timer_t timer = EG(max_execution_timer_timer); -# ifdef MAX_EXECUTION_TIMERS_DEBUG +# ifdef MAX_EXECUTION_TIMERS_DEBUG fprintf(stderr, "Deleting timer %#jx on thread %d...\n", (uintmax_t) timer, (pid_t) syscall(SYS_gettid)); -# endif +# endif int err = timer_delete(timer); if (err != 0) { @@ -121,4 +211,5 @@ void zend_max_execution_timer_shutdown(void) /* {{{ */ } /* }}}} */ +# endif #endif diff --git a/Zend/zend_max_execution_timer.h b/Zend/zend_max_execution_timer.h index 789f50e6b7dcd..4e4a2e6e3455d 100644 --- a/Zend/zend_max_execution_timer.h +++ b/Zend/zend_max_execution_timer.h @@ -21,6 +21,12 @@ #include "zend_long.h" +# ifdef __APPLE__ +#define ZEND_MAX_EXECUTION_TIMERS_SIGNAL SIGALRM +# else +#define ZEND_MAX_EXECUTION_TIMERS_SIGNAL SIGRTMIN +# endif + /* Must be called after calls to fork() */ ZEND_API void zend_max_execution_timer_init(void); void zend_max_execution_timer_settime(zend_long seconds); From 83e87225bc146fd53d825ab138f6365d0365bcb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 22 Feb 2024 01:01:37 +0100 Subject: [PATCH 2/8] non-ZTS support --- Zend/zend_max_execution_timer.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Zend/zend_max_execution_timer.c b/Zend/zend_max_execution_timer.c index f36e35ce0dc31..2906115b79e02 100644 --- a/Zend/zend_max_execution_timer.c +++ b/Zend/zend_max_execution_timer.c @@ -30,14 +30,18 @@ static inline void zend_max_execution_timer_handler(void *arg) { +#ifdef ZTS pthread_t *tid = (pthread_t *) arg; pthread_kill(*tid, ZEND_MAX_EXECUTION_TIMERS_SIGNAL); +#else + pid_t *pid = (pid_t *) arg; + kill(*pid, ZEND_MAX_EXECUTION_TIMERS_SIGNAL); +#endif } static inline void zend_max_execution_timer_cancel(void *arg) { - pthread_t *tid = (pthread_t *) arg; - free(tid); + free(arg); } ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ @@ -58,10 +62,14 @@ ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ EG(max_execution_timer_suspended) = 1; # ifdef ZTS - pthread_t lpid = pthread_self(); - pthread_t *tid = malloc(sizeof(pthread_t)); - memcpy(tid, &lpid, sizeof(pthread_t)); - dispatch_set_context(EG(max_execution_timer_timer), tid); + pthread_t tid = pthread_self(); + pthread_t *ptid = malloc(sizeof(pthread_t)); + memcpy(ptid, &tid, sizeof(pthread_t)); + dispatch_set_context(EG(max_execution_timer_timer), ptid); +#else + pid_t *ppid = malloc(sizeof(pid_t)); + *ppid = pid; + dispatch_set_context(EG(max_execution_timer_timer), ppid) # endif dispatch_source_set_event_handler_f(EG(max_execution_timer_timer), zend_max_execution_timer_handler); From aa7813d3054a43b869c0b242c0f60a6fd62fd47c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 22 Feb 2024 17:41:51 +0100 Subject: [PATCH 3/8] fix non-ZTS support --- Zend/Zend.m4 | 6 +++++- Zend/zend_max_execution_timer.c | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index 6750c62a20599..7405cb793a937 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -297,12 +297,16 @@ fi AC_MSG_CHECKING(whether to enable zend signal handling) AC_MSG_RESULT($ZEND_SIGNALS) + +dnl Enable Zend Max Execution Timers by default on macOS +AS_CASE(["$host_alias"], [*darwin*], [ZEND_MAX_EXECUTION_TIMERS="yes"], [ZEND_MAX_EXECUTION_TIMERS=$ZEND_ZTS]) + dnl Don't enable Zend Max Execution Timers by default until PHP 8.3 to not break the ABI AC_ARG_ENABLE([zend-max-execution-timers], [AS_HELP_STRING([--enable-zend-max-execution-timers], [whether to enable zend max execution timers])], [ZEND_MAX_EXECUTION_TIMERS=$enableval], - [ZEND_MAX_EXECUTION_TIMERS=$ZEND_ZTS]) + []) AS_CASE( ["$host_alias"], diff --git a/Zend/zend_max_execution_timer.c b/Zend/zend_max_execution_timer.c index 2906115b79e02..0e3a96a9d69ed 100644 --- a/Zend/zend_max_execution_timer.c +++ b/Zend/zend_max_execution_timer.c @@ -21,6 +21,8 @@ #include # ifdef ZTS #include +# else +#include # endif #include "zend.h" @@ -69,7 +71,7 @@ ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ #else pid_t *ppid = malloc(sizeof(pid_t)); *ppid = pid; - dispatch_set_context(EG(max_execution_timer_timer), ppid) + dispatch_set_context(EG(max_execution_timer_timer), ppid); # endif dispatch_source_set_event_handler_f(EG(max_execution_timer_timer), zend_max_execution_timer_handler); From 0abb2358cfafd275c4ad7050072f41332b908ebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 23 Feb 2024 16:24:53 +0100 Subject: [PATCH 4/8] Arnaud's review --- Zend/zend_execute_API.c | 12 ++++++------ Zend/zend_globals.h | 2 +- Zend/zend_max_execution_timer.c | 22 +++++++++++----------- Zend/zend_max_execution_timer.h | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 0aa126e35b3f9..f1d13d9ccb839 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1403,19 +1403,19 @@ ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void) /* {{{ */ # ifdef ZEND_MAX_EXECUTION_TIMERS static void zend_timeout_handler(int dummy, siginfo_t *si, void *uc) /* {{{ */ { -#ifdef ZTS +# 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 +# endif -#ifndef __APPLE__ +# ifndef __APPLE__ if (si->si_value.sival_ptr != &EG(max_execution_timer_timer)) { -#ifdef MAX_EXECUTION_TIMERS_DEBUG +# 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 +# endif if (EG(oldact).sa_sigaction) { EG(oldact).sa_sigaction(dummy, si, uc); @@ -1426,7 +1426,7 @@ static void zend_timeout_handler(int dummy, siginfo_t *si, void *uc) /* {{{ */ return; } -#endif +# endif /* ifndef __APPLE__ */ # else static void zend_timeout_handler(int dummy) /* {{{ */ { diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index ff6d8d0bd9d50..65a19fb69f817 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -303,7 +303,7 @@ struct _zend_executor_globals { #ifdef ZEND_MAX_EXECUTION_TIMERS # ifdef __APPLE__ - dispatch_source_t max_execution_timer_timer; + dispatch_source_t max_execution_timer_source; bool max_execution_timer_suspended; # else timer_t max_execution_timer_timer; diff --git a/Zend/zend_max_execution_timer.c b/Zend/zend_max_execution_timer.c index 0e3a96a9d69ed..c251395880731 100644 --- a/Zend/zend_max_execution_timer.c +++ b/Zend/zend_max_execution_timer.c @@ -55,8 +55,8 @@ ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ } dispatch_queue_global_t queue = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0); - EG(max_execution_timer_timer) = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); - if (EG(max_execution_timer_timer) == NULL) { + EG(max_execution_timer_source) = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); + if (EG(max_execution_timer_source) == NULL) { zend_strerror_noreturn(E_ERROR, errno, "Could not create dispatch source"); } @@ -67,22 +67,22 @@ ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ pthread_t tid = pthread_self(); pthread_t *ptid = malloc(sizeof(pthread_t)); memcpy(ptid, &tid, sizeof(pthread_t)); - dispatch_set_context(EG(max_execution_timer_timer), ptid); + dispatch_set_context(EG(max_execution_timer_source), ptid); #else pid_t *ppid = malloc(sizeof(pid_t)); *ppid = pid; - dispatch_set_context(EG(max_execution_timer_timer), ppid); + dispatch_set_context(EG(max_execution_timer_source), ppid); # endif - dispatch_source_set_event_handler_f(EG(max_execution_timer_timer), zend_max_execution_timer_handler); - dispatch_source_set_cancel_handler_f(EG(max_execution_timer_timer), zend_max_execution_timer_cancel); + dispatch_source_set_event_handler_f(EG(max_execution_timer_source), zend_max_execution_timer_handler); + dispatch_source_set_cancel_handler_f(EG(max_execution_timer_source), zend_max_execution_timer_cancel); } /* }}} */ void zend_max_execution_timer_settime(zend_long seconds) /* {{{ */ { if (seconds == 0) { if (!EG(max_execution_timer_suspended)) { - dispatch_suspend(EG(max_execution_timer_timer)); + dispatch_suspend(EG(max_execution_timer_source)); EG(max_execution_timer_suspended) = 1; } @@ -90,13 +90,13 @@ void zend_max_execution_timer_settime(zend_long seconds) /* {{{ */ } dispatch_source_set_timer( - EG(max_execution_timer_timer), + EG(max_execution_timer_source), dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC), seconds * NSEC_PER_SEC, 0 ); if (EG(max_execution_timer_suspended)) { - dispatch_resume(EG(max_execution_timer_timer)); + dispatch_resume(EG(max_execution_timer_source)); EG(max_execution_timer_suspended) = 0; } } /* }}} */ @@ -110,8 +110,8 @@ void zend_max_execution_timer_shutdown(void) /* {{{ */ EG(pid) = 0; - dispatch_source_cancel(EG(max_execution_timer_timer)); - //dispatch_release(EG(max_execution_timer_timer)); + dispatch_source_cancel(EG(max_execution_timer_source)); + //dispatch_release(EG(max_execution_timer_source)); } /* }}} */ # else diff --git a/Zend/zend_max_execution_timer.h b/Zend/zend_max_execution_timer.h index 4e4a2e6e3455d..491fd74d06a7c 100644 --- a/Zend/zend_max_execution_timer.h +++ b/Zend/zend_max_execution_timer.h @@ -22,7 +22,7 @@ #include "zend_long.h" # ifdef __APPLE__ -#define ZEND_MAX_EXECUTION_TIMERS_SIGNAL SIGALRM +#define ZEND_MAX_EXECUTION_TIMERS_SIGNAL SIGIO # else #define ZEND_MAX_EXECUTION_TIMERS_SIGNAL SIGRTMIN # endif From 535929497f6716a88b443161853c8b32bb64252a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 23 Feb 2024 18:42:24 +0100 Subject: [PATCH 5/8] call zend_timeout_handler directly --- Zend/zend_execute.h | 4 ++++ Zend/zend_execute_API.c | 4 ++++ Zend/zend_max_execution_timer.c | 9 +++------ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 71512ccf1b122..a3439808292ce 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -400,6 +400,10 @@ ZEND_API zend_class_entry *zend_fetch_class(zend_string *class_name, uint32_t fe ZEND_API zend_class_entry *zend_fetch_class_with_scope(zend_string *class_name, uint32_t fetch_type, zend_class_entry *scope); ZEND_API zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, zend_string *lcname, uint32_t fetch_type); +#if defined(__APPLE__) && !defined(ZTS) +void zend_timeout_handler(void); +#endif + ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name); ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function_str(const char *name, size_t len); ZEND_API void ZEND_FASTCALL zend_init_func_run_time_cache(zend_op_array *op_array); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index f1d13d9ccb839..321de7a13d541 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1401,7 +1401,11 @@ ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void) /* {{{ */ #ifndef ZEND_WIN32 # ifdef ZEND_MAX_EXECUTION_TIMERS +# if defined(__APPLE__) && !defined(ZTS) +void zend_timeout_handler(void) /* {{{ */ +# else static void zend_timeout_handler(int dummy, siginfo_t *si, void *uc) /* {{{ */ +# endif { # ifdef ZTS if (!tsrm_is_managed_thread()) { diff --git a/Zend/zend_max_execution_timer.c b/Zend/zend_max_execution_timer.c index c251395880731..5440256d4e74d 100644 --- a/Zend/zend_max_execution_timer.c +++ b/Zend/zend_max_execution_timer.c @@ -22,7 +22,7 @@ # ifdef ZTS #include # else -#include +#include "zend_execute.h" # endif #include "zend.h" @@ -36,8 +36,7 @@ static inline void zend_max_execution_timer_handler(void *arg) pthread_t *tid = (pthread_t *) arg; pthread_kill(*tid, ZEND_MAX_EXECUTION_TIMERS_SIGNAL); #else - pid_t *pid = (pid_t *) arg; - kill(*pid, ZEND_MAX_EXECUTION_TIMERS_SIGNAL); + zend_timeout_handler(); #endif } @@ -69,9 +68,7 @@ ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ memcpy(ptid, &tid, sizeof(pthread_t)); dispatch_set_context(EG(max_execution_timer_source), ptid); #else - pid_t *ppid = malloc(sizeof(pid_t)); - *ppid = pid; - dispatch_set_context(EG(max_execution_timer_source), ppid); + //dispatch_set_context(EG(max_execution_timer_source), NULL); # endif dispatch_source_set_event_handler_f(EG(max_execution_timer_source), zend_max_execution_timer_handler); From 54b4daf21c7e83c351e1954e293394261957e64d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 23 Feb 2024 19:07:05 +0100 Subject: [PATCH 6/8] fix --- Zend/zend_execute_API.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 321de7a13d541..7168ec04c8a04 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1543,6 +1543,7 @@ static void zend_set_timeout_ex(zend_long seconds, bool reset_signals) /* {{{ */ #elif defined(ZEND_MAX_EXECUTION_TIMERS) zend_max_execution_timer_settime(seconds); +# if !defined(__APPLE__) || defined(ZTS) if (reset_signals) { sigset_t sigset; struct sigaction act; @@ -1556,6 +1557,7 @@ static void zend_set_timeout_ex(zend_long seconds, bool reset_signals) /* {{{ */ sigaddset(&sigset, ZEND_MAX_EXECUTION_TIMERS_SIGNAL); sigprocmask(SIG_UNBLOCK, &sigset, NULL); } +# endif #elif defined(HAVE_SETITIMER) { struct itimerval t_r; /* timeout requested */ From 956a6113e990b61a389faa7c0288cf544a5ecfc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 26 Feb 2024 15:52:07 +0100 Subject: [PATCH 7/8] debug log --- sapi/fpm/tests/status-listen.phpt | 1 + 1 file changed, 1 insertion(+) diff --git a/sapi/fpm/tests/status-listen.phpt b/sapi/fpm/tests/status-listen.phpt index fb400c8d62467..e9b471229d299 100644 --- a/sapi/fpm/tests/status-listen.phpt +++ b/sapi/fpm/tests/status-listen.phpt @@ -9,6 +9,7 @@ require_once "tester.inc"; $cfg = << Date: Fri, 1 Mar 2024 18:12:00 +0100 Subject: [PATCH 8/8] Apply suggestions from code review Co-authored-by: Peter Kokot --- Zend/Zend.m4 | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index 7405cb793a937..fbf2943266632 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -311,20 +311,14 @@ AC_ARG_ENABLE([zend-max-execution-timers], AS_CASE( ["$host_alias"], [*linux*|*freebsd*], [ - PHP_CHECK_FUNC(timer_create, rt) - if test "$ac_cv_func_timer_create" != "yes"; then - ZEND_MAX_EXECUTION_TIMERS='no' - fi + AC_SEARCH_LIBS([timer_create], [rt],, [ZEND_MAX_EXECUTION_TIMERS='no']) ], [*darwin*], [], [ZEND_MAX_EXECUTION_TIMERS='no'] ) AS_CASE(["$host_alias"], [*darwin*], [], [ - PHP_CHECK_FUNC(timer_create, rt) - if test "$ac_cv_func_timer_create" != "yes"; then - ZEND_MAX_EXECUTION_TIMERS='no' - fi + AC_SEARCH_LIBS([timer_create], [rt],, [ZEND_MAX_EXECUTION_TIMERS='no']) ]) if test "$ZEND_MAX_EXECUTION_TIMERS" = "yes"; then