int sig_dispatch(pid_t pid, FAR siginfo_t *info) { #ifdef HAVE_GROUP_MEMBERS FAR struct tcb_s *stcb; FAR struct task_group_s *group; /* Get the TCB associated with the pid */ stcb = sched_gettcb(pid); if (stcb) { /* The task/thread associated with this PID is still active. Get its * task group. */ group = stcb->group; } else { /* The task/thread associated with this PID has exited. In the normal * usage model, the PID should correspond to the PID of the task that * created the task group. Try looking it up. */ group = group_findbypid(pid); } /* Did we locate the group? */ if (group) { /* Yes.. call group_signal() to send the signal to the correct group * member. */ return group_signal(group, info); } else { return -ESRCH; } #else FAR struct tcb_s *stcb; /* Get the TCB associated with the pid */ stcb = sched_gettcb(pid); if (!stcb) { return -ESRCH; } return sig_tcbdispatch(stcb, info); #endif }
static inline void task_sigchild(gid_t pgid, FAR struct tcb_s *ctcb, int status) { FAR struct task_group_s *chgrp = ctcb->group; FAR struct task_group_s *pgrp; siginfo_t info; DEBUGASSERT(chgrp); /* Get the parent task group. It is possible that all of the members of * the parent task group have exited. This would not be an error. In * this case, the child task group has been orphaned. */ pgrp = group_findbygid(pgid); if (!pgrp) { /* Set the task group ID to an invalid group ID. The dead parent * task group ID could get reused some time in the future. */ chgrp->tg_pgid = INVALID_GROUP_ID; return; } /* Save the exit status now if this is the main thread of the task group * that is exiting. Only the exiting main task of a task group carries * interpretable exit Check if this is the main task that is exiting. */ #ifndef CONFIG_DISABLE_PTHREAD if ((ctcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD) #endif { task_exitstatus(pgrp, status); } /* But only the final exiting thread in a task group, whatever it is, * should generate SIGCHLD. */ if (chgrp->tg_nmembers == 1) { /* Mark that all of the threads in the task group have exited */ task_groupexit(pgrp); /* Create the siginfo structure. We don't actually know the cause. * That is a bug. Let's just say that the child task just exited * for now. */ info.si_signo = SIGCHLD; info.si_code = CLD_EXITED; info.si_errno = OK; info.si_value.sival_ptr = NULL; #ifndef CONFIG_DISABLE_PTHREAD info.si_pid = chgrp->tg_task; #else info.si_pid = ctcb->pid; #endif info.si_status = status; /* Send the signal to one thread in the group */ (void)group_signal(pgrp, &info); } }