Skip to content

Commit fd5a756

Browse files
committed
Revive Zend Signals handler (and fixed bug #61083)
1 parent c498cc7 commit fd5a756

File tree

5 files changed

+44
-52
lines changed

5 files changed

+44
-52
lines changed

Zend/zend.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,10 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) /
715715
tsrm_set_new_thread_end_handler(zend_new_thread_end_handler);
716716
#endif
717717

718+
#ifdef ZEND_SIGNALS
719+
zend_signal_startup();
720+
#endif
721+
718722
return SUCCESS;
719723
}
720724
/* }}} */
@@ -769,9 +773,6 @@ void zend_post_startup(void) /* {{{ */
769773

770774
void zend_shutdown(void) /* {{{ */
771775
{
772-
#ifdef ZEND_SIGNALS
773-
zend_signal_shutdown();
774-
#endif
775776
zend_destroy_rsrc_list(&EG(persistent_list));
776777
if (EG(active))
777778
{

Zend/zend_signal.c

+33-41
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ void zend_signal_handler_defer(int signo, siginfo_t *siginfo, void *context)
7575
int errno_save = errno;
7676
zend_signal_queue_t *queue, *qtmp;
7777

78-
if (SIGG(active)) {
79-
if (SIGG(depth) == 0) { /* try to handle signal */
80-
if (SIGG(blocked) != -1) { /* inverse */
81-
SIGG(blocked) = -1; /* signal is not blocked */
78+
if (EXPECTED(SIGG(active))) {
79+
if (UNEXPECTED(SIGG(depth) == 0)) { /* try to handle signal */
80+
if (UNEXPECTED(SIGG(blocked))) {
81+
SIGG(blocked) = 0;
8282
}
83-
if (SIGG(running) == 0) {
83+
if (EXPECTED(SIGG(running) == 0)) {
8484
SIGG(running) = 1;
8585
zend_signal_handler(signo, siginfo, context);
8686

@@ -98,7 +98,7 @@ void zend_signal_handler_defer(int signo, siginfo_t *siginfo, void *context)
9898
SIGG(running) = 0;
9999
}
100100
} else { /* delay signal handling */
101-
SIGG(blocked) = 0; /* signal is blocked */
101+
SIGG(blocked) = 1; /* signal is blocked */
102102

103103
if ((queue = SIGG(pavail))) { /* if none available it's simply forgotton */
104104
SIGG(pavail) = queue->next;
@@ -135,7 +135,7 @@ ZEND_API void zend_signal_handler_unblock(void)
135135
zend_signal_queue_t *queue;
136136
zend_signal_t zend_signal;
137137

138-
if (SIGG(active)) {
138+
if (EXPECTED(SIGG(active))) {
139139
SIGNAL_BEGIN_CRITICAL(); /* procmask to protect handler_defer as if it were called by the kernel */
140140
queue = SIGG(phead);
141141
SIGG(phead) = queue->next;
@@ -282,7 +282,7 @@ void zend_signal_activate(void)
282282

283283
memcpy(&SIGG(handlers), &global_orig_handlers, sizeof(global_orig_handlers));
284284

285-
for (x=0; x < sizeof(zend_sigs) / sizeof(*zend_sigs); x++) {
285+
for (x = 0; x < sizeof(zend_sigs) / sizeof(*zend_sigs); x++) {
286286
zend_signal_register(zend_sigs[x], zend_signal_handler_defer);
287287
}
288288

@@ -294,15 +294,15 @@ void zend_signal_activate(void)
294294
* */
295295
void zend_signal_deactivate(void)
296296
{
297-
int x;
298-
struct sigaction sa = {{0}};
299297

300298
if (SIGG(check)) {
299+
int x;
300+
struct sigaction sa = {{0}};
301301
if (SIGG(depth) != 0) {
302302
zend_error(E_CORE_WARNING, "zend_signal: shutdown with non-zero blocking depth (%d)", SIGG(depth));
303303
}
304304
/* did anyone steal our installed handler */
305-
for (x=0; x < sizeof(zend_sigs) / sizeof(*zend_sigs); x++) {
305+
for (x = 0; x < sizeof(zend_sigs) / sizeof(*zend_sigs); x++) {
306306
sigaction(zend_sigs[x], NULL, &sa);
307307
if (sa.sa_sigaction != zend_signal_handler_defer) {
308308
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)
313313
SIGNAL_BEGIN_CRITICAL();
314314
SIGG(active) = 0;
315315
SIGG(running) = 0;
316-
SIGG(blocked) = -1;
316+
SIGG(blocked) = 0;
317317
SIGG(depth) = 0;
318318
SIGNAL_END_CRITICAL();
319319
}
320320
/* }}} */
321321

322-
static void zend_signal_globals_ctor(zend_signal_globals_t *zend_signal_globals)
322+
static void zend_signal_globals_ctor(zend_signal_globals_t *zend_signal_globals) /* {{{ */
323323
{
324324
size_t x;
325325

326326
memset(zend_signal_globals, 0, sizeof(*zend_signal_globals));
327-
zend_signal_globals->blocked = -1;
328327

329328
for (x = 0; x < sizeof(zend_signal_globals->pstorage) / sizeof(*zend_signal_globals->pstorage); ++x) {
330329
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)
333332
zend_signal_globals->pavail = queue;
334333
}
335334
}
335+
/* }}} */
336336

337-
static void zend_signal_globals_dtor(zend_signal_globals_t *zend_signal_globals)
337+
void zend_signal_init() /* {{{ */
338338
{
339-
zend_signal_globals->blocked = -1;
339+
int signo;
340+
struct sigaction sa = {{0}};
341+
342+
/* Save previously registered signal handlers into orig_handlers */
343+
memset(&global_orig_handlers, 0, sizeof(global_orig_handlers));
344+
for (signo = 1; signo < NSIG; ++signo) {
345+
if (sigaction(signo, NULL, &sa) == 0) {
346+
global_orig_handlers[signo-1].flags = sa.sa_flags;
347+
if (sa.sa_flags & SA_SIGINFO) {
348+
global_orig_handlers[signo-1].handler = (void *) sa.sa_sigaction;
349+
} else {
350+
global_orig_handlers[signo-1].handler = (void *) sa.sa_handler;
351+
}
352+
}
353+
}
340354
}
355+
/* }}} */
341356

342357
/* {{{ zend_signal_startup
343358
* alloc zend signal globals */
344359
void zend_signal_startup()
345360
{
346-
int signo;
347-
struct sigaction sa = {{0}};
348361

349362
#ifdef ZTS
350-
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);
363+
ts_allocate_id(&zend_signal_globals_id, sizeof(zend_signal_globals_t), (ts_allocate_ctor) zend_signal_globals_ctor, NULL);
351364
#else
352365
zend_signal_globals_ctor(&zend_signal_globals);
353366
#endif
@@ -374,28 +387,7 @@ void zend_signal_startup()
374387
sigdelset(&global_sigmask, SIGTRAP);
375388
#endif
376389

377-
/* Save previously registered signal handlers into orig_handlers */
378-
memset(&global_orig_handlers, 0, sizeof(global_orig_handlers));
379-
for (signo = 1; signo < NSIG; ++signo) {
380-
if (sigaction(signo, NULL, &sa) == 0) {
381-
global_orig_handlers[signo-1].flags = sa.sa_flags;
382-
if (sa.sa_flags & SA_SIGINFO) {
383-
global_orig_handlers[signo-1].handler = (void *) sa.sa_sigaction;
384-
} else {
385-
global_orig_handlers[signo-1].handler = (void *) sa.sa_handler;
386-
}
387-
}
388-
}
389-
}
390-
/* }}} */
391-
392-
/* {{{ zend_signal_shutdown
393-
* called by zend_shutdown */
394-
void zend_signal_shutdown(void)
395-
{
396-
#ifndef ZTS
397-
zend_signal_globals_dtor(&zend_signal_globals);
398-
#endif
390+
zend_signal_init();
399391
}
400392
/* }}} */
401393

Zend/zend_signal.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,9 @@ typedef struct _zend_signal_queue_t {
5555
/* Signal Globals */
5656
typedef struct _zend_signal_globals_t {
5757
int depth;
58-
int blocked; /* 0==TRUE, -1==FALSE */
58+
int blocked; /* 1==TRUE, 0==FALSE */
5959
int running; /* in signal handler execution */
6060
int active; /* internal signal handling is enabled */
61-
int initialized; /* memory initialized */
6261
zend_bool check; /* check for replaced handlers on shutdown */
6362
zend_signal_entry_t handlers[NSIG];
6463
zend_signal_queue_t pstorage[ZEND_SIGNAL_QUEUE_SIZE], *phead, *ptail, *pavail; /* pending queue */
@@ -70,12 +69,12 @@ BEGIN_EXTERN_C()
7069
ZEND_API extern int zend_signal_globals_id;
7170
END_EXTERN_C()
7271
# define ZEND_SIGNAL_BLOCK_INTERRUPUTIONS() if (EXPECTED(zend_signal_globals_id)) { SIGG(depth)++; }
73-
# define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() if (EXPECTED(zend_signal_globals_id) && UNEXPECTED((--SIGG(depth))==SIGG(blocked))) { zend_signal_handler_unblock(); }
72+
# define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() if (EXPECTED(zend_signal_globals_id) && UNEXPECTED(((SIGG(depth)--) == SIGG(blocked)))) { zend_signal_handler_unblock(); }
7473
#else /* ZTS */
7574
# define SIGG(v) (zend_signal_globals.v)
7675
extern ZEND_API zend_signal_globals_t zend_signal_globals;
7776
# define ZEND_SIGNAL_BLOCK_INTERRUPUTIONS() SIGG(depth)++;
78-
# define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() if (UNEXPECTED((--SIGG(depth))==SIGG(blocked))) { zend_signal_handler_unblock(); }
77+
# define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() if (((SIGG(depth)--) == SIGG(blocked))) { zend_signal_handler_unblock(); }
7978
#endif /* not ZTS */
8079

8180
# define SIGNAL_BEGIN_CRITICAL() sigset_t oldmask; \
@@ -87,6 +86,7 @@ ZEND_API void zend_signal_handler_unblock();
8786
void zend_signal_activate(void);
8887
void zend_signal_deactivate(void);
8988
void zend_signal_startup();
89+
void zend_signal_init();
9090
void zend_signal_shutdown(void);
9191
ZEND_API int zend_signal(int signo, void (*handler)(int));
9292
ZEND_API int zend_sigaction(int signo, const struct sigaction *act, struct sigaction *oldact);

main/SAPI.c

-4
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,6 @@ SAPI_API sapi_module_struct sapi_module;
8383

8484
SAPI_API void sapi_startup(sapi_module_struct *sf)
8585
{
86-
#ifdef ZEND_SIGNALS
87-
zend_signal_startup();
88-
#endif
89-
9086
sf->ini_entries = NULL;
9187
sapi_module = *sf;
9288

sapi/apache2handler/sapi_apache2.c

+3
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,9 @@ void php_ap2_register_hook(apr_pool_t *p)
717717
ap_hook_pre_config(php_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
718718
ap_hook_post_config(php_apache_server_startup, NULL, NULL, APR_HOOK_MIDDLE);
719719
ap_hook_handler(php_handler, NULL, NULL, APR_HOOK_MIDDLE);
720+
#ifdef ZEND_SIGNALS
721+
ap_hook_child_init(zend_signal_init, NULL, NULL, APR_HOOK_MIDDLE);
722+
#endif
720723
ap_hook_child_init(php_apache_child_init, NULL, NULL, APR_HOOK_MIDDLE);
721724
}
722725

0 commit comments

Comments
 (0)