mirror of
https://github.com/php/php-src.git
synced 2026-03-24 08:12:21 +01:00
Merge branch 'PHP-8.2'
* PHP-8.2: Revert the fix for GH-11498
This commit is contained in:
@@ -1048,68 +1048,26 @@ static void pcntl_signal_handler(int signo, siginfo_t *siginfo, void *context)
|
||||
static void pcntl_signal_handler(int signo)
|
||||
#endif
|
||||
{
|
||||
struct php_pcntl_pending_signal *psig_first = PCNTL_G(spares);
|
||||
if (!psig_first) {
|
||||
struct php_pcntl_pending_signal *psig = PCNTL_G(spares);
|
||||
if (!psig) {
|
||||
/* oops, too many signals for us to track, so we'll forget about this one */
|
||||
return;
|
||||
}
|
||||
|
||||
struct php_pcntl_pending_signal *psig = NULL;
|
||||
|
||||
/* Standard signals may be merged into a single one.
|
||||
* POSIX specifies that SIGCHLD has the si_pid field (https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html),
|
||||
* so we'll handle the merging for that signal.
|
||||
* See also: https://www.gnu.org/software/libc/manual/html_node/Merged-Signals.html */
|
||||
if (signo == SIGCHLD) {
|
||||
/* Note: The first waitpid result is not necessarily the pid that was passed above!
|
||||
* We therefore cannot avoid the first waitpid() call. */
|
||||
int status;
|
||||
pid_t pid;
|
||||
while (true) {
|
||||
do {
|
||||
errno = 0;
|
||||
/* Although Linux specifies that WNOHANG will never result in EINTR, POSIX doesn't say so:
|
||||
* https://pubs.opengroup.org/onlinepubs/9699919799/functions/waitpid.html */
|
||||
pid = waitpid(-1, &status, WNOHANG | WUNTRACED);
|
||||
} while (pid <= 0 && errno == EINTR);
|
||||
if (pid <= 0) {
|
||||
if (UNEXPECTED(!psig)) {
|
||||
/* The child might've been consumed by another thread and will be handled there. */
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
psig = psig ? psig->next : psig_first;
|
||||
psig->signo = signo;
|
||||
|
||||
#ifdef HAVE_STRUCT_SIGINFO_T
|
||||
psig->siginfo = *siginfo;
|
||||
psig->siginfo.si_pid = pid;
|
||||
#endif
|
||||
|
||||
if (UNEXPECTED(!psig->next)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
psig = psig_first;
|
||||
psig->signo = signo;
|
||||
|
||||
#ifdef HAVE_STRUCT_SIGINFO_T
|
||||
psig->siginfo = *siginfo;
|
||||
#endif
|
||||
}
|
||||
|
||||
PCNTL_G(spares) = psig->next;
|
||||
|
||||
psig->signo = signo;
|
||||
psig->next = NULL;
|
||||
|
||||
#ifdef HAVE_STRUCT_SIGINFO_T
|
||||
psig->siginfo = *siginfo;
|
||||
#endif
|
||||
|
||||
/* the head check is important, as the tick handler cannot atomically clear both
|
||||
* the head and tail */
|
||||
if (PCNTL_G(head) && PCNTL_G(tail)) {
|
||||
PCNTL_G(tail)->next = psig_first;
|
||||
PCNTL_G(tail)->next = psig;
|
||||
} else {
|
||||
PCNTL_G(head) = psig_first;
|
||||
PCNTL_G(head) = psig;
|
||||
}
|
||||
PCNTL_G(tail) = psig;
|
||||
PCNTL_G(pending_signals) = 1;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
GH-11498 (SIGCHLD is not always returned from proc_open)
|
||||
Waiting on SIGCHLD with a pcntl_wait() loop
|
||||
--EXTENSIONS--
|
||||
pcntl
|
||||
--SKIPIF--
|
||||
@@ -14,8 +14,10 @@ $processes = [];
|
||||
|
||||
pcntl_async_signals(true);
|
||||
pcntl_signal(SIGCHLD, function($sig, $info) use (&$processes) {
|
||||
echo "SIGCHLD\n";
|
||||
unset($processes[$info['pid']]);
|
||||
while (($pid = pcntl_wait($status, WUNTRACED | WNOHANG)) > 0) {
|
||||
echo "SIGCHLD\n";
|
||||
unset($processes[$pid]);
|
||||
}
|
||||
}, false);
|
||||
|
||||
for ($i = 0; $i <= 5; $i++) {
|
||||
Reference in New Issue
Block a user