* 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:
parent
cc30d340c3
commit
268fe0f839
@ -1302,11 +1302,19 @@ get_death_entry(struct team *team, pid_t child, struct death_entry *death,
|
|||||||
struct process_group *group;
|
struct process_group *group;
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
|
// TODO: only *children* are of interest, not any process of a given ID (see bug #996)!
|
||||||
|
|
||||||
if (child == -1 || child > 0) {
|
if (child == -1 || child > 0) {
|
||||||
// wait for any children or a specific child of this team to die
|
// wait for any children or a specific child of this team to die
|
||||||
*_waitSem = team->dead_children.sem;
|
status = team_get_death_entry(team, child, death, _freeDeath);
|
||||||
*_waitCount = &team->dead_children.waiters;
|
if (status < B_OK) {
|
||||||
return team_get_death_entry(team, child, death, _freeDeath);
|
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) {
|
} else if (child < 0) {
|
||||||
// we wait for all children of the specified process group
|
// we wait for all children of the specified process group
|
||||||
group = team_get_process_group_locked(team->group->session, -child);
|
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;
|
*_waitSem = group->dead_child_sem;
|
||||||
*_waitCount = &group->dead_child_waiters;
|
*_waitCount = &group->dead_child_waiters;
|
||||||
return B_WOULD_BLOCK;
|
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)
|
if ((flags & WNOHANG) != 0)
|
||||||
status = B_WOULD_BLOCK;
|
status = B_WOULD_BLOCK;
|
||||||
|
|
||||||
// TODO: check if this check is correct
|
// make sure this child is one of ours
|
||||||
if (childThread->team->group_id != team->group_id)
|
if (childThread->team->parent != team)
|
||||||
status = ECHILD;
|
status = ECHILD;
|
||||||
|
|
||||||
childExists = true;
|
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 (status == B_BAD_THREAD_ID) {
|
||||||
if (child <= 0 || !childExists) {
|
if (child <= 0 || !childExists) {
|
||||||
status = ECHILD;
|
status = ECHILD;
|
||||||
|
RELEASE_TEAM_LOCK();
|
||||||
|
restore_interrupts(state);
|
||||||
goto err;
|
goto err;
|
||||||
} else {
|
} else {
|
||||||
// the specific child we're waiting for is still running
|
// the specific child we're waiting for is still running
|
||||||
|
Loading…
Reference in New Issue
Block a user