mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
fixed bug #52784 (Race condition when handling many
concurrent signals)
This commit is contained in:
parent
a9507474e3
commit
61e7730ee8
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user