diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index 119de2356f2..4eb58997f4c 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -1392,6 +1392,7 @@ void pcntl_signal_dispatch(void) queue = PCNTL_G(head); PCNTL_G(head) = NULL; /* simple stores are atomic */ + PCNTL_G(tail) = NULL; /* Allocate */ while (queue) { @@ -1411,6 +1412,9 @@ void pcntl_signal_dispatch(void) #ifdef HAVE_STRUCT_SIGINFO_T zval_ptr_dtor(¶ms[1]); #endif + if (EG(exception)) { + break; + } } } @@ -1420,6 +1424,14 @@ void pcntl_signal_dispatch(void) queue = next; } + /* drain the remaining in case of exception thrown */ + while (queue) { + next = queue->next; + queue->next = PCNTL_G(spares); + PCNTL_G(spares) = queue; + queue = next; + } + PCNTL_G(pending_signals) = false; /* Re-enable queue */ diff --git a/ext/pcntl/tests/pcntl_signal_dispatch_exception.phpt b/ext/pcntl/tests/pcntl_signal_dispatch_exception.phpt new file mode 100644 index 00000000000..06c4f827c6e --- /dev/null +++ b/ext/pcntl/tests/pcntl_signal_dispatch_exception.phpt @@ -0,0 +1,34 @@ +--TEST-- +pcntl_signal_dispatch() stops dispatching after handler throws exception +--EXTENSIONS-- +pcntl +posix +--FILE-- +getMessage() . "\n"; +} + +echo "Handlers called: " . implode(', ', $called) . "\n"; + +?> +--EXPECT-- +Exception in signal handler +Handlers called: SIGUSR1