* 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
This commit is contained in:
Axel Dörfler 2007-01-28 14:31:42 +00:00
parent cc30d340c3
commit 268fe0f839

View File

@ -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
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 team_get_death_entry(team, child, death, _freeDeath);
}
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