* The parent/group dead semaphores are now released a bit earlier to make
wait_for_child() hanging less probable - there is a general problem with this code, though, as we need to have a dedicated free counter for the semaphore to remove all race conditions. * Also, test fork_3-1 still sometimes fails because the thread is still available to the public for a short time, even after its death entry has been collected. * Added a TODO in the code for these issues. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18529 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -855,6 +855,7 @@ thread_exit2(void *_args)
|
|||||||
remove_thread_from_team(team_get_kernel_team(), args.thread);
|
remove_thread_from_team(team_get_kernel_team(), args.thread);
|
||||||
RELEASE_TEAM_LOCK();
|
RELEASE_TEAM_LOCK();
|
||||||
|
|
||||||
|
// TODO: this needs to be done earlier, so that this thread cannot be found on its last trip
|
||||||
GRAB_THREAD_LOCK();
|
GRAB_THREAD_LOCK();
|
||||||
hash_remove(sThreadHash, args.thread);
|
hash_remove(sThreadHash, args.thread);
|
||||||
sUsedThreads--;
|
sUsedThreads--;
|
||||||
@@ -905,7 +906,7 @@ thread_exit(void)
|
|||||||
struct death_entry *death = NULL;
|
struct death_entry *death = NULL;
|
||||||
thread_id mainParentThread = -1;
|
thread_id mainParentThread = -1;
|
||||||
bool deleteTeam = false;
|
bool deleteTeam = false;
|
||||||
sem_id cachedDeathSem = -1, parentDeadSem = -1, groupDeadSem = -1;
|
sem_id cachedDeathSem = -1;
|
||||||
status_t status;
|
status_t status;
|
||||||
struct thread_debug_info debugInfo;
|
struct thread_debug_info debugInfo;
|
||||||
team_id teamID = team->id;
|
team_id teamID = team->id;
|
||||||
@@ -1005,8 +1006,13 @@ thread_exit(void)
|
|||||||
} else
|
} else
|
||||||
death = NULL;
|
death = NULL;
|
||||||
|
|
||||||
parentDeadSem = parent->dead_children.sem;
|
// notify listeners that a new death entry is available
|
||||||
groupDeadSem = team->group->dead_child_sem;
|
// TODO: should that be moved to handle_signal() (for SIGCHLD)?
|
||||||
|
// TODO: B_RELEASE_ALL opens up a race condition with wait_for_child().
|
||||||
|
release_sem_etc(parent->dead_children.sem, 0,
|
||||||
|
B_RELEASE_ALL | B_DO_NOT_RESCHEDULE);
|
||||||
|
release_sem_etc(team->group->dead_child_sem, 0,
|
||||||
|
B_RELEASE_ALL | B_DO_NOT_RESCHEDULE);
|
||||||
}
|
}
|
||||||
|
|
||||||
team_remove_team(team, &freeGroup);
|
team_remove_team(team, &freeGroup);
|
||||||
@@ -1021,11 +1027,6 @@ thread_exit(void)
|
|||||||
|
|
||||||
// delete the team if we're its main thread
|
// delete the team if we're its main thread
|
||||||
if (deleteTeam) {
|
if (deleteTeam) {
|
||||||
// notify listeners that a new death entry is available
|
|
||||||
// ToDo: should that be moved to handle_signal() (for SIGCHLD)?
|
|
||||||
release_sem_etc(parentDeadSem, 0, B_RELEASE_ALL | B_DO_NOT_RESCHEDULE);
|
|
||||||
release_sem_etc(groupDeadSem, 0, B_RELEASE_ALL | B_DO_NOT_RESCHEDULE);
|
|
||||||
|
|
||||||
team_delete_process_group(freeGroup);
|
team_delete_process_group(freeGroup);
|
||||||
team_delete_team(team);
|
team_delete_team(team);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user