system/nxinit: Avoid SIGCHLD race with ppoll()

Pending all signals(SIGCHLD) when ppoll() is not invoked to
avoid race conditions.

Case reproduction

  Set examples/hello as a service that exits immediately after startup.

  ```init.rc
  on boot
     start hello

  service hello hello
     restart_period 0
  ```

  Log - without this patch:

    # Service hello only restarts about 100 times, ppoll is not woken up
    # after the hello process with PID 119 exits.

    [    4.391274] [ 2] [ 0] init_main: service 'hello' pid 118 exited status 0
    [    4.401423] [ 2] [ 0] init_main: started service 'hello' pid 119

  Log - with this patch:

    # ppoll() can still be woken up normally after tens of thousands of
    # restarts of service hello in stress test.

    [  268.447747] [ 2] [ 0] init_main: service 'hello' pid 34503 exited status 0

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
This commit is contained in:
wangjianyu3 2025-12-19 21:54:19 +08:00
parent 825aeee19e
commit aed85cb99a

View file

@ -154,9 +154,19 @@ int main(int argc, FAR char *argv[])
};
struct pollfd pfds[nitems(ev)];
sigset_t mask;
size_t i;
int r;
sigfillset(&mask);
r = sigprocmask(SIG_BLOCK, &mask, NULL);
sigemptyset(&mask);
if (r < 0)
{
init_err("sigprocmask failed %d", errno);
return r;
}
#ifdef CONFIG_USBDEV_TRACE
usbtrace_enable(TRACE_BITSET);
#endif
@ -215,7 +225,7 @@ int main(int argc, FAR char *argv[])
break;
}
r = ppoll(pfds, nitems(pfds), MS2TIMESPEC(&timeout, t), NULL);
r = ppoll(pfds, nitems(pfds), MS2TIMESPEC(&timeout, t), &mask);
if (r < 0 && errno != EINTR)
{
init_err("Wait event");