From 268fe0f839262604da32b7056c5be4999131bfc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 28 Jan 2007 14:31:42 +0000 Subject: [PATCH] * wait_for_child() now checks if the team has any children to wait for, and returns ECHILD in case it doesn't. This fixes bug #995. * Added a TODO item for solving bug #996. * wait_for_child() did not release the team lock and restore interrupts in case the child you wanted to wait for didn't exist... * with child > 0, wait_for_child() will now check if its really a child of yours, and not just in the same process group. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19993 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/team.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/system/kernel/team.c b/src/system/kernel/team.c index 95d2602296..debfbe41f5 100644 --- a/src/system/kernel/team.c +++ b/src/system/kernel/team.c @@ -1302,11 +1302,19 @@ get_death_entry(struct team *team, pid_t child, struct death_entry *death, struct process_group *group; status_t status; + // TODO: only *children* are of interest, not any process of a given ID (see bug #996)! + if (child == -1 || child > 0) { // wait for any children or a specific child of this team to die - *_waitSem = team->dead_children.sem; - *_waitCount = &team->dead_children.waiters; - return team_get_death_entry(team, child, death, _freeDeath); + status = team_get_death_entry(team, child, death, _freeDeath); + if (status < B_OK) { + if (team->children == NULL) + return B_BAD_THREAD_ID; + + *_waitSem = team->dead_children.sem; + *_waitCount = &team->dead_children.waiters; + } + return status; } else if (child < 0) { // we wait for all children of the specified process group group = team_get_process_group_locked(team->group->session, -child); @@ -1325,6 +1333,10 @@ get_death_entry(struct team *team, pid_t child, struct death_entry *death, } } + // does this team have any children we would need to wait for? + if (team->children == NULL) + return B_BAD_THREAD_ID; + *_waitSem = group->dead_child_sem; *_waitCount = &group->dead_child_waiters; return B_WOULD_BLOCK; @@ -1373,8 +1385,8 @@ wait_for_child(thread_id child, uint32 flags, int32 *_reason, status_t *_returnC if ((flags & WNOHANG) != 0) status = B_WOULD_BLOCK; - // TODO: check if this check is correct - if (childThread->team->group_id != team->group_id) + // make sure this child is one of ours + if (childThread->team->parent != team) status = ECHILD; childExists = true; @@ -1398,6 +1410,8 @@ wait_for_child(thread_id child, uint32 flags, int32 *_reason, status_t *_returnC if (status == B_BAD_THREAD_ID) { if (child <= 0 || !childExists) { status = ECHILD; + RELEASE_TEAM_LOCK(); + restore_interrupts(state); goto err; } else { // the specific child we're waiting for is still running