3737#include "zend_weakrefs.h"
3838#include "zend_inheritance.h"
3939#include "zend_observer.h"
40- #ifdef HAVE_SYS_TIME_H
41- #include <sys/time.h>
42- #endif
43- #ifdef HAVE_UNISTD_H
44- #include <unistd.h>
45- #endif
46- #if defined(ZTS ) && defined(HAVE_TIMER_CREATE )
47- #include <time.h>
48- #include <sys/syscall.h>
49- #include <sys/types.h>
50- // Musl Libc defines this macro, glibc does not
51- // According to "man 2 timer_create" this field should always be available, but it's not
52- # ifndef sigev_notify_thread_id
53- # define sigev_notify_thread_id _sigev_un._tid
54- # endif
55- #endif
40+ #include "zend_timer.h"
5641
5742ZEND_API void (* zend_execute_ex )(zend_execute_data * execute_data );
5843ZEND_API void (* zend_execute_internal )(zend_execute_data * execute_data , zval * return_value );
@@ -181,23 +166,6 @@ void init_executor(void) /* {{{ */
181166 EG (vm_interrupt ) = 0 ;
182167 EG (timed_out ) = 0 ;
183168
184- #if defined(ZTS ) && defined(HAVE_TIMER_CREATE )
185- struct sigevent sev ;
186- sev .sigev_notify = SIGEV_THREAD_ID ;
187- sev .sigev_value .sival_ptr = & EG (timer );
188- sev .sigev_signo = SIGIO ;
189- sev .sigev_notify_thread_id = (pid_t ) syscall (SYS_gettid );
190-
191- if (timer_create (CLOCK_THREAD_CPUTIME_ID , & sev , & EG (timer )) != 0 ) {
192- # ifdef TIMER_DEBUG
193- fprintf (stderr , "error %d while creating timer %#jx on thread %d\n" , errno , (uintmax_t ) EG (timer ), (pid_t ) syscall (SYS_gettid ));
194- # endif
195- }
196- # ifdef TIMER_DEBUG
197- else fprintf (stderr , "timer %#jx created on thread %d\n" , (uintmax_t ) EG (timer ), syscall (SYS_gettid ));
198- # endif
199- #endif
200-
201169 EG (exception ) = NULL ;
202170 EG (prev_exception ) = NULL ;
203171
@@ -413,6 +381,26 @@ ZEND_API void zend_shutdown_executor_values(bool fast_shutdown)
413381 zend_objects_store_free_object_storage (& EG (objects_store ), fast_shutdown );
414382}
415383
384+ #ifdef ZEND_TIMER
385+ static void zend_timer_settime (zend_long seconds ) /* {{{ }*/
386+ {
387+ timer_t timer = EG (timer );
388+ if (timer == 0 ) zend_error_noreturn (E_ERROR , "Timer not created" );
389+
390+ struct itimerspec its ;
391+ its .it_value .tv_sec = seconds ;
392+ its .it_value .tv_nsec = its .it_interval .tv_sec = its .it_interval .tv_nsec = 0 ;
393+
394+ int errn = timer_settime (timer , 0 , & its , NULL );
395+ if (errn != 0 ) zend_strerror_noreturn (E_ERROR , errn , "Could not set timer" );
396+
397+ # ifdef TIMER_DEBUG
398+ fprintf (stderr , "Timer %#jx set on thread %d (%ld seconds)\n" , (uintmax_t ) timer , (pid_t ) syscall (SYS_gettid ), seconds );
399+ # endif
400+ }
401+ /* }}} */
402+ #endif
403+
416404void shutdown_executor (void ) /* {{{ */
417405{
418406 zend_string * key ;
@@ -423,17 +411,6 @@ void shutdown_executor(void) /* {{{ */
423411 bool fast_shutdown = is_zend_mm () && !EG (full_tables_cleanup );
424412#endif
425413
426- #if defined(ZTS ) && defined(HAVE_TIMER_CREATE )
427- if (timer_delete (EG (timer )) != 0 ) {
428- # ifdef TIMER_DEBUG
429- fprintf (stderr , "error %d while deleting timer %#jx on thread %d\n" , errno , (uintmax_t ) EG (timer ), (pid_t ) syscall (SYS_gettid ));
430- # endif
431- }
432- # ifdef TIMER_DEBUG
433- else fprintf (stderr , "timer %#jx deleted on thread %d\n" , (uintmax_t ) EG (timer ), (pid_t ) syscall (SYS_gettid ));
434- # endif
435- #endif
436-
437414 zend_try {
438415 zend_stream_shutdown ();
439416 } zend_end_try ();
@@ -1352,7 +1329,7 @@ ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void) /* {{{ */
13521329/* }}} */
13531330
13541331#ifndef ZEND_WIN32
1355- # if defined( ZTS ) && defined( HAVE_TIMER_CREATE )
1332+ # ifdef ZEND_TIMER
13561333static void zend_timeout_handler (int dummy , siginfo_t * si , void * uc ) /* {{{ */
13571334{
13581335 if (si -> si_value .sival_ptr != & EG (timer )) {
@@ -1465,25 +1442,8 @@ static void zend_set_timeout_ex(zend_long seconds, bool reset_signals) /* {{{ */
14651442 zend_error_noreturn (E_ERROR , "Could not queue new timer" );
14661443 return ;
14671444 }
1468- #elif defined(ZTS ) && defined(HAVE_TIMER_CREATE )
1469- timer_t timer = EG (timer );
1470- struct itimerspec its ;
1471-
1472- its .it_value .tv_sec = seconds ;
1473- its .it_value .tv_nsec = 0 ;
1474- its .it_interval .tv_sec = 0 ;
1475- its .it_interval .tv_nsec = 0 ;
1476-
1477- if (timer_settime (timer , 0 , & its , NULL ) != 0 ) {
1478- #ifdef TIMER_DEBUG
1479- fprintf (stderr , "unable to set timer %#jx on thread %d\n" , (uintmax_t ) timer , (pid_t ) syscall (SYS_gettid ));
1480- #endif
1481-
1482- return ;
1483- }
1484- # ifdef TIMER_DEBUG
1485- else fprintf (stderr , "timer %#jx set on thread %d (%ld seconds)\n" , (uintmax_t ) timer , (pid_t ) syscall (SYS_gettid ), seconds );
1486- # endif
1445+ #elif defined(ZEND_TIMER )
1446+ zend_timer_settime (seconds );
14871447
14881448 if (reset_signals ) {
14891449 sigset_t sigset ;
@@ -1562,6 +1522,8 @@ void zend_unset_timeout(void) /* {{{ */
15621522 }
15631523 tq_timer = NULL ;
15641524 }
1525+ #elif ZEND_TIMER
1526+ zend_timer_settime (0 );
15651527#elif defined(HAVE_SETITIMER )
15661528 if (EG (timeout_seconds )) {
15671529 struct itimerval no_timeout ;
0 commit comments