From bce576c0bd3d25f41f4fb084a2f8a921805d140d Mon Sep 17 00:00:00 2001 From: Yoshinori Sugino Date: Fri, 4 Dec 2020 15:20:40 +0900 Subject: [PATCH] sched/sched/sched_waitid.c: Discard the child entry Summary: - Discard the child entry after receiving SIGCHLD. Impact: - waitid Testing: hifive1-revb:nsh (CONFIG_SCHED_HAVE_PARENT=y, CONFIG_SCHED_CHILD_STATUS=y, CONFIG_SIG_DEFAULT=y) on QEMU static int task_main(int argc, char *argv[]) { sleep(1); return 0; } int main(int argc, FAR char *argv[]) { pid_t pid; siginfo_t info; int ret; pid = task_create("task1", 224, 1024, task_main, NULL); task_create("task2", 224, 1024, task_main, NULL); waitid(P_PID, pid, &info, WEXITED); waitid(P_ALL, 0, &info, WEXITED); ret = waitid(P_ALL, 0, &info, WEXITED | WNOHANG); assert(ret == -1); return 0; } --- sched/sched/sched_waitid.c | 41 ++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/sched/sched/sched_waitid.c b/sched/sched/sched_waitid.c index 8aac1122dc..3b119d3143 100644 --- a/sched/sched/sched_waitid.c +++ b/sched/sched/sched_waitid.c @@ -74,12 +74,15 @@ static void exited_child(FAR struct tcb_s *rtcb, * information). */ - info->si_signo = SIGCHLD; - info->si_code = CLD_EXITED; - info->si_errno = OK; - info->si_value.sival_ptr = NULL; - info->si_pid = child->ch_pid; - info->si_status = child->ch_status; + if (info) + { + info->si_signo = SIGCHLD; + info->si_code = CLD_EXITED; + info->si_errno = OK; + info->si_value.sival_ptr = NULL; + info->si_pid = child->ch_pid; + info->si_status = child->ch_status; + } /* Discard the child entry */ @@ -364,6 +367,19 @@ int nx_waitid(int idtype, id_t id, FAR siginfo_t *info, int options) { /* Yes... return success */ +#ifdef CONFIG_SCHED_CHILD_STATUS + if (retains) + { + child = group_find_child(rtcb->group, info->si_pid); + DEBUGASSERT(child); + + if ((child->ch_flags & CHILD_FLAG_EXITED) != 0) + { + exited_child(rtcb, child, NULL); + } + } +#endif + break; } } @@ -374,6 +390,19 @@ int nx_waitid(int idtype, id_t id, FAR siginfo_t *info, int options) { /* Return success */ +#ifdef CONFIG_SCHED_CHILD_STATUS + if (retains) + { + child = group_find_child(rtcb->group, info->si_pid); + + if (child && + (child->ch_flags & CHILD_FLAG_EXITED) != 0) + { + exited_child(rtcb, child, NULL); + } + } +#endif + break; }