diff options
| author | Arnaud Le Blanc <lbarnaud@php.net> | 2010-11-01 22:29:25 +0000 |
|---|---|---|
| committer | Arnaud Le Blanc <lbarnaud@php.net> | 2010-11-01 22:29:25 +0000 |
| commit | 61e7730ee89ad86e8b56f262f9d5ae698b445a8a (patch) | |
| tree | ceea8bd07392267dea218db0a5689f3a7cad6abd /ext | |
| parent | a9507474e3ec43dbffc83875229ee155a425f94d (diff) | |
| download | php-git-61e7730ee89ad86e8b56f262f9d5ae698b445a8a.tar.gz | |
fixed bug #52784 (Race condition when handling many
concurrent signals)
Diffstat (limited to 'ext')
| -rwxr-xr-x | ext/pcntl/pcntl.c | 11 | ||||
| -rw-r--r-- | ext/pcntl/php_signal.c | 13 | ||||
| -rw-r--r-- | ext/pcntl/php_signal.h | 1 |
3 files changed, 22 insertions, 3 deletions
diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index 7c5dc0ea06..de5b99e9b6 100755 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -887,7 +887,7 @@ PHP_FUNCTION(pcntl_signal) zend_hash_index_update(&PCNTL_G(php_signal_table), signo, (void **) &handle, sizeof(zval *), (void **) &dest_handle); if (dest_handle) zval_add_ref(dest_handle); - if (php_signal(signo, pcntl_signal_handler, (int) restart_syscalls) == SIG_ERR) { + if (php_signal4(signo, pcntl_signal_handler, (int) restart_syscalls, 1) == SIG_ERR) { PCNTL_G(last_error) = errno; php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error assigning signal"); RETURN_FALSE; @@ -1224,7 +1224,13 @@ void pcntl_signal_dispatch() { zval *param, **handle, *retval; struct php_pcntl_pending_signal *queue, *next; + sigset_t mask; + sigset_t old_mask; TSRMLS_FETCH(); + + /* Mask all signals */ + sigfillset(&mask); + sigprocmask(SIG_BLOCK, &mask, &old_mask); /* Bail if the queue is empty or if we are already playing the queue*/ if (! PCNTL_G(head) || PCNTL_G(processing_signal_queue)) @@ -1260,6 +1266,9 @@ void pcntl_signal_dispatch() /* Re-enable queue */ PCNTL_G(processing_signal_queue) = 0; + + /* return signal mask to previous state */ + sigprocmask(SIG_SETMASK, &old_mask, NULL); } diff --git a/ext/pcntl/php_signal.c b/ext/pcntl/php_signal.c index 6963e6ff37..d3f86d0f12 100644 --- a/ext/pcntl/php_signal.c +++ b/ext/pcntl/php_signal.c @@ -22,11 +22,15 @@ /* php_signal using sigaction is derrived from Advanced Programing * in the Unix Environment by W. Richard Stevens p 298. */ -Sigfunc *php_signal(int signo, Sigfunc *func, int restart) +Sigfunc *php_signal4(int signo, Sigfunc *func, int restart, int mask_all) { struct sigaction act,oact; act.sa_handler = func; - sigemptyset(&act.sa_mask); + if (mask_all) { + sigfillset(&act.sa_mask); + } else { + sigemptyset(&act.sa_mask); + } act.sa_flags = 0; if (signo == SIGALRM || (! restart)) { #ifdef SA_INTERRUPT @@ -43,6 +47,11 @@ Sigfunc *php_signal(int signo, Sigfunc *func, int restart) return oact.sa_handler; } +Sigfunc *php_signal(int signo, Sigfunc *func, int restart) +{ + return php_signal4(signo, func, restart, 0); +} + /* * Local variables: * tab-width: 4 diff --git a/ext/pcntl/php_signal.h b/ext/pcntl/php_signal.h index f9e7a5af15..cb9a1a767c 100644 --- a/ext/pcntl/php_signal.h +++ b/ext/pcntl/php_signal.h @@ -31,5 +31,6 @@ typedef void Sigfunc(int); Sigfunc *php_signal(int signo, Sigfunc *func, int restart); +Sigfunc *php_signal4(int signo, Sigfunc *func, int restart, int mask_all); #endif |
