signal: fix group signal can't dispatch some parent group twice

reproduce:

static void *pthread(void *arg)
{
  system(arg);
}

void test (int argc, char *argv[])
{
  pthread_create(&pthread0, &attr, pthread, argv[1]);
  pthread_create(&pthread1, &attr, pthread, argv[2]);
}

only one pthread system() returnd, othres hanged

rootcause:

As we known, system() will create a new task called:
system -c XX

The example:
parent group               child groups

pthread0 -> waitpid() -> system -c ps -> exit() -> nxtask_signalparent()
pthread1 -> waitpid() -> system -c ls -> exit() -> nxtask_signalparent()

Each child group exit with function nxtask_signalparent(),

As we expect:

system -c ps will signal pthread0
system -c ls will signal pthread1

But actually:

system -c ps will signal pthread0/1
system -c ls will signal pthread0/1

As the spec, we know, this behavior is normal:
https://man7.org/linux/man-pages/man2/sigwaitinfo.2.html

So for this situation, when the signo is SIGCHLD, we broadcast.

Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
ligd 2023-06-21 22:40:52 +08:00 committed by Xiang Xiao
parent 5c798dd297
commit 1552e52e14

View File

@ -99,7 +99,7 @@ static int group_signal_handler(pid_t pid, FAR void *arg)
*/
ret = nxsig_ismember(&tcb->sigwaitmask, info->siginfo->si_signo);
if (ret == 1 && !info->atcb)
if (ret == 1 && (!info->atcb || info->siginfo->si_signo == SIGCHLD))
{
/* Yes.. This means that the task is suspended, waiting for this
* signal to occur. Stop looking and use this TCB. The
@ -118,7 +118,8 @@ static int group_signal_handler(pid_t pid, FAR void *arg)
/* Limit to one thread */
info->atcb = tcb;
if (info->ptcb != NULL)
if (info->ptcb != NULL && info->siginfo->si_signo != SIGCHLD)
{
return 1; /* Terminate the search */
}