From fd5a756ad44124ffa7e9a5810a31ff49e91708cf Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Thu, 5 Mar 2015 18:11:22 +0800 Subject: [PATCH] Revive Zend Signals handler (and fixed bug #61083) --- Zend/zend.c | 7 +-- Zend/zend_signal.c | 74 +++++++++++++----------------- Zend/zend_signal.h | 8 ++-- main/SAPI.c | 4 -- sapi/apache2handler/sapi_apache2.c | 3 ++ 5 files changed, 44 insertions(+), 52 deletions(-) diff --git a/Zend/zend.c b/Zend/zend.c index 50857bc688c..8d6cd7148fe 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -715,6 +715,10 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) / tsrm_set_new_thread_end_handler(zend_new_thread_end_handler); #endif +#ifdef ZEND_SIGNALS + zend_signal_startup(); +#endif + return SUCCESS; } /* }}} */ @@ -769,9 +773,6 @@ void zend_post_startup(void) /* {{{ */ void zend_shutdown(void) /* {{{ */ { -#ifdef ZEND_SIGNALS - zend_signal_shutdown(); -#endif zend_destroy_rsrc_list(&EG(persistent_list)); if (EG(active)) { diff --git a/Zend/zend_signal.c b/Zend/zend_signal.c index bf061b36ca4..88193033514 100644 --- a/Zend/zend_signal.c +++ b/Zend/zend_signal.c @@ -75,12 +75,12 @@ void zend_signal_handler_defer(int signo, siginfo_t *siginfo, void *context) int errno_save = errno; zend_signal_queue_t *queue, *qtmp; - if (SIGG(active)) { - if (SIGG(depth) == 0) { /* try to handle signal */ - if (SIGG(blocked) != -1) { /* inverse */ - SIGG(blocked) = -1; /* signal is not blocked */ + if (EXPECTED(SIGG(active))) { + if (UNEXPECTED(SIGG(depth) == 0)) { /* try to handle signal */ + if (UNEXPECTED(SIGG(blocked))) { + SIGG(blocked) = 0; } - if (SIGG(running) == 0) { + if (EXPECTED(SIGG(running) == 0)) { SIGG(running) = 1; zend_signal_handler(signo, siginfo, context); @@ -98,7 +98,7 @@ void zend_signal_handler_defer(int signo, siginfo_t *siginfo, void *context) SIGG(running) = 0; } } else { /* delay signal handling */ - SIGG(blocked) = 0; /* signal is blocked */ + SIGG(blocked) = 1; /* signal is blocked */ if ((queue = SIGG(pavail))) { /* if none available it's simply forgotton */ SIGG(pavail) = queue->next; @@ -135,7 +135,7 @@ ZEND_API void zend_signal_handler_unblock(void) zend_signal_queue_t *queue; zend_signal_t zend_signal; - if (SIGG(active)) { + if (EXPECTED(SIGG(active))) { SIGNAL_BEGIN_CRITICAL(); /* procmask to protect handler_defer as if it were called by the kernel */ queue = SIGG(phead); SIGG(phead) = queue->next; @@ -282,7 +282,7 @@ void zend_signal_activate(void) memcpy(&SIGG(handlers), &global_orig_handlers, sizeof(global_orig_handlers)); - for (x=0; x < sizeof(zend_sigs) / sizeof(*zend_sigs); x++) { + for (x = 0; x < sizeof(zend_sigs) / sizeof(*zend_sigs); x++) { zend_signal_register(zend_sigs[x], zend_signal_handler_defer); } @@ -294,15 +294,15 @@ void zend_signal_activate(void) * */ void zend_signal_deactivate(void) { - int x; - struct sigaction sa = {{0}}; if (SIGG(check)) { + int x; + struct sigaction sa = {{0}}; if (SIGG(depth) != 0) { zend_error(E_CORE_WARNING, "zend_signal: shutdown with non-zero blocking depth (%d)", SIGG(depth)); } /* did anyone steal our installed handler */ - for (x=0; x < sizeof(zend_sigs) / sizeof(*zend_sigs); x++) { + for (x = 0; x < sizeof(zend_sigs) / sizeof(*zend_sigs); x++) { sigaction(zend_sigs[x], NULL, &sa); if (sa.sa_sigaction != zend_signal_handler_defer) { zend_error(E_CORE_WARNING, "zend_signal: handler was replaced for signal (%d) after startup", zend_sigs[x]); @@ -313,18 +313,17 @@ void zend_signal_deactivate(void) SIGNAL_BEGIN_CRITICAL(); SIGG(active) = 0; SIGG(running) = 0; - SIGG(blocked) = -1; + SIGG(blocked) = 0; SIGG(depth) = 0; SIGNAL_END_CRITICAL(); } /* }}} */ -static void zend_signal_globals_ctor(zend_signal_globals_t *zend_signal_globals) +static void zend_signal_globals_ctor(zend_signal_globals_t *zend_signal_globals) /* {{{ */ { size_t x; memset(zend_signal_globals, 0, sizeof(*zend_signal_globals)); - zend_signal_globals->blocked = -1; for (x = 0; x < sizeof(zend_signal_globals->pstorage) / sizeof(*zend_signal_globals->pstorage); ++x) { zend_signal_queue_t *queue = &zend_signal_globals->pstorage[x]; @@ -333,21 +332,35 @@ static void zend_signal_globals_ctor(zend_signal_globals_t *zend_signal_globals) zend_signal_globals->pavail = queue; } } +/* }}} */ -static void zend_signal_globals_dtor(zend_signal_globals_t *zend_signal_globals) +void zend_signal_init() /* {{{ */ { - zend_signal_globals->blocked = -1; + int signo; + struct sigaction sa = {{0}}; + + /* Save previously registered signal handlers into orig_handlers */ + memset(&global_orig_handlers, 0, sizeof(global_orig_handlers)); + for (signo = 1; signo < NSIG; ++signo) { + if (sigaction(signo, NULL, &sa) == 0) { + global_orig_handlers[signo-1].flags = sa.sa_flags; + if (sa.sa_flags & SA_SIGINFO) { + global_orig_handlers[signo-1].handler = (void *) sa.sa_sigaction; + } else { + global_orig_handlers[signo-1].handler = (void *) sa.sa_handler; + } + } + } } +/* }}} */ /* {{{ zend_signal_startup * alloc zend signal globals */ void zend_signal_startup() { - int signo; - struct sigaction sa = {{0}}; #ifdef ZTS - ts_allocate_id(&zend_signal_globals_id, sizeof(zend_signal_globals_t), (ts_allocate_ctor) zend_signal_globals_ctor, (ts_allocate_dtor) zend_signal_globals_dtor); + ts_allocate_id(&zend_signal_globals_id, sizeof(zend_signal_globals_t), (ts_allocate_ctor) zend_signal_globals_ctor, NULL); #else zend_signal_globals_ctor(&zend_signal_globals); #endif @@ -374,28 +387,7 @@ void zend_signal_startup() sigdelset(&global_sigmask, SIGTRAP); #endif - /* Save previously registered signal handlers into orig_handlers */ - memset(&global_orig_handlers, 0, sizeof(global_orig_handlers)); - for (signo = 1; signo < NSIG; ++signo) { - if (sigaction(signo, NULL, &sa) == 0) { - global_orig_handlers[signo-1].flags = sa.sa_flags; - if (sa.sa_flags & SA_SIGINFO) { - global_orig_handlers[signo-1].handler = (void *) sa.sa_sigaction; - } else { - global_orig_handlers[signo-1].handler = (void *) sa.sa_handler; - } - } - } -} -/* }}} */ - -/* {{{ zend_signal_shutdown - * called by zend_shutdown */ -void zend_signal_shutdown(void) -{ -#ifndef ZTS - zend_signal_globals_dtor(&zend_signal_globals); -#endif + zend_signal_init(); } /* }}} */ diff --git a/Zend/zend_signal.h b/Zend/zend_signal.h index 2f33ccb5b7e..e70e409b4ba 100644 --- a/Zend/zend_signal.h +++ b/Zend/zend_signal.h @@ -55,10 +55,9 @@ typedef struct _zend_signal_queue_t { /* Signal Globals */ typedef struct _zend_signal_globals_t { int depth; - int blocked; /* 0==TRUE, -1==FALSE */ + int blocked; /* 1==TRUE, 0==FALSE */ int running; /* in signal handler execution */ int active; /* internal signal handling is enabled */ - int initialized; /* memory initialized */ zend_bool check; /* check for replaced handlers on shutdown */ zend_signal_entry_t handlers[NSIG]; zend_signal_queue_t pstorage[ZEND_SIGNAL_QUEUE_SIZE], *phead, *ptail, *pavail; /* pending queue */ @@ -70,12 +69,12 @@ BEGIN_EXTERN_C() ZEND_API extern int zend_signal_globals_id; END_EXTERN_C() # define ZEND_SIGNAL_BLOCK_INTERRUPUTIONS() if (EXPECTED(zend_signal_globals_id)) { SIGG(depth)++; } -# define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() if (EXPECTED(zend_signal_globals_id) && UNEXPECTED((--SIGG(depth))==SIGG(blocked))) { zend_signal_handler_unblock(); } +# define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() if (EXPECTED(zend_signal_globals_id) && UNEXPECTED(((SIGG(depth)--) == SIGG(blocked)))) { zend_signal_handler_unblock(); } #else /* ZTS */ # define SIGG(v) (zend_signal_globals.v) extern ZEND_API zend_signal_globals_t zend_signal_globals; # define ZEND_SIGNAL_BLOCK_INTERRUPUTIONS() SIGG(depth)++; -# define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() if (UNEXPECTED((--SIGG(depth))==SIGG(blocked))) { zend_signal_handler_unblock(); } +# define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() if (((SIGG(depth)--) == SIGG(blocked))) { zend_signal_handler_unblock(); } #endif /* not ZTS */ # define SIGNAL_BEGIN_CRITICAL() sigset_t oldmask; \ @@ -87,6 +86,7 @@ ZEND_API void zend_signal_handler_unblock(); void zend_signal_activate(void); void zend_signal_deactivate(void); void zend_signal_startup(); +void zend_signal_init(); void zend_signal_shutdown(void); ZEND_API int zend_signal(int signo, void (*handler)(int)); ZEND_API int zend_sigaction(int signo, const struct sigaction *act, struct sigaction *oldact); diff --git a/main/SAPI.c b/main/SAPI.c index 95a2c7df5c2..d23907ce81f 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -83,10 +83,6 @@ SAPI_API sapi_module_struct sapi_module; SAPI_API void sapi_startup(sapi_module_struct *sf) { -#ifdef ZEND_SIGNALS - zend_signal_startup(); -#endif - sf->ini_entries = NULL; sapi_module = *sf; diff --git a/sapi/apache2handler/sapi_apache2.c b/sapi/apache2handler/sapi_apache2.c index ed4c9f30df0..bca9d872a57 100644 --- a/sapi/apache2handler/sapi_apache2.c +++ b/sapi/apache2handler/sapi_apache2.c @@ -717,6 +717,9 @@ void php_ap2_register_hook(apr_pool_t *p) ap_hook_pre_config(php_pre_config, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_post_config(php_apache_server_startup, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_handler(php_handler, NULL, NULL, APR_HOOK_MIDDLE); +#ifdef ZEND_SIGNALS + ap_hook_child_init(zend_signal_init, NULL, NULL, APR_HOOK_MIDDLE); +#endif ap_hook_child_init(php_apache_child_init, NULL, NULL, APR_HOOK_MIDDLE); }