3 // parent and child processes share the same handler here
4 function handler($signo) {
6 if ($signo == SIGUSR2
) {
7 if (SignalChangeHandlerAfterForkPhp
::$child == 0) {
8 echo "child: I received SIGUSR2...\n";
9 echo "child: sending SIGUSR1 to inform parent\n";
10 posix_kill(SignalChangeHandlerAfterForkPhp
::$parent, SIGUSR1
);
13 echo "parent: I received SIGUSR2, switching to new handler\n";
14 pcntl_signal(SIGUSR1
, newhandler
<>);
15 pcntl_signal(SIGUSR2
, newhandler
<>);
16 echo "parent: sending SIGUSR2 to child as ack\n";
17 posix_kill(SignalChangeHandlerAfterForkPhp
::$child, SIGUSR2
);
19 } else if ($signo == SIGUSR1
) {
20 if (SignalChangeHandlerAfterForkPhp
::$child != 0) {
21 echo "parent: received SIGUSR1 from child\n";
23 pcntl_waitpid(SignalChangeHandlerAfterForkPhp
::$child, inout
$status);
24 echo "child exit with code $status";
30 function newhandler($signo) {
32 echo "parent: new handler invoked\n";
34 pcntl_waitpid(SignalChangeHandlerAfterForkPhp
::$child, inout
$status);
38 function waitForSignal($nsec) {
39 for ($i = 0; $i < $nsec; ++
$i) {
45 pcntl_signal(SIGUSR1
, handler
<>);
46 pcntl_signal(SIGUSR2
, handler
<>);
48 SignalChangeHandlerAfterForkPhp
::$child = pcntl_fork(); // 0 in the child process
50 // FIXME(T80291213): fix race condition in dbgo mode
53 if (SignalChangeHandlerAfterForkPhp
::$child == 0) {
54 echo "do some work in child process\n";
55 posix_kill(SignalChangeHandlerAfterForkPhp
::$parent, SIGUSR2
);
61 echo "this shouldn't be printed.";
64 abstract final class SignalChangeHandlerAfterForkPhp
{
65 public static $parent;
69 function entrypoint_change_handler_after_fork(): void
{
71 SignalChangeHandlerAfterForkPhp
::$parent = posix_getpid();
72 SignalChangeHandlerAfterForkPhp
::$child = 0;