Skip to content

Commit

Permalink
fixed bug #52784 (Race condition when handling many
Browse files Browse the repository at this point in the history
concurrent signals)
  • Loading branch information
arnaud-lb committed Nov 1, 2010
1 parent a950747 commit 61e7730
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 3 deletions.
11 changes: 10 additions & 1 deletion ext/pcntl/pcntl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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);
}


Expand Down
13 changes: 11 additions & 2 deletions ext/pcntl/php_signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions ext/pcntl/php_signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 61e7730

Please sign in to comment.