svn: /php/php-src/trunk/ext/pcntl/ pcntl.c php_signal.c php_signal.h
| From: | Arnaud Le Blanc | Date: | Mon, 01 Nov 2010 22:29:25 +0000 |
| Subject: | svn: /php/php-src/trunk/ext/pcntl/ pcntl.c php_signal.c php_signal.h | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-63736@lists.php.net to get a copy of this message | ||
lbarnaud Mon, 01 Nov 2010 22:29:25 +0000
Revision: http://svn.php.net/viewvc?view=revision&revision=305018
Log:
fixed bug #52784 (Race condition when handling many
concurrent signals)
Bug: http://bugs.php.net/52784 (Assigned) Race condition
when handling many concurrent signals
Changed paths:
U php/php-src/trunk/ext/pcntl/pcntl.c
U php/php-src/trunk/ext/pcntl/php_signal.c
U php/php-src/trunk/ext/pcntl/php_signal.h
Modified: php/php-src/trunk/ext/pcntl/pcntl.c
===================================================================
--- php/php-src/trunk/ext/pcntl/pcntl.c 2010-11-01 20:31:39 UTC (rev 305017)
+++ php/php-src/trunk/ext/pcntl/pcntl.c 2010-11-01 22:29:25 UTC (rev 305018)
@@ -887,7 +887,7 @@
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 @@
{
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 @@
/* Re-enable queue */
PCNTL_G(processing_signal_queue) = 0;
+
+ /* return signal mask to previous state */
+ sigprocmask(SIG_SETMASK, &old_mask, NULL);
}
Modified: php/php-src/trunk/ext/pcntl/php_signal.c
===================================================================
--- php/php-src/trunk/ext/pcntl/php_signal.c 2010-11-01 20:31:39 UTC (rev 305017)
+++ php/php-src/trunk/ext/pcntl/php_signal.c 2010-11-01 22:29:25 UTC (rev 305018)
@@ -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 @@
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
Modified: php/php-src/trunk/ext/pcntl/php_signal.h
===================================================================
--- php/php-src/trunk/ext/pcntl/php_signal.h 2010-11-01 20:31:39 UTC (rev 305017)
+++ php/php-src/trunk/ext/pcntl/php_signal.h 2010-11-01 22:29:25 UTC (rev 305018)
@@ -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