From 79dd3d935a45a31e42f8739e5d799b2dc532dc01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 17 Aug 2006 21:45:37 +0000 Subject: [PATCH] * 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 --- src/system/kernel/thread.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/system/kernel/thread.c b/src/system/kernel/thread.c index 396a8b5d73..f592956f9c 100644 --- a/src/system/kernel/thread.c +++ b/src/system/kernel/thread.c @@ -855,6 +855,7 @@ thread_exit2(void *_args) remove_thread_from_team(team_get_kernel_team(), args.thread); RELEASE_TEAM_LOCK(); + // TODO: this needs to be done earlier, so that this thread cannot be found on its last trip GRAB_THREAD_LOCK(); hash_remove(sThreadHash, args.thread); sUsedThreads--; @@ -905,7 +906,7 @@ thread_exit(void) struct death_entry *death = NULL; thread_id mainParentThread = -1; bool deleteTeam = false; - sem_id cachedDeathSem = -1, parentDeadSem = -1, groupDeadSem = -1; + sem_id cachedDeathSem = -1; status_t status; struct thread_debug_info debugInfo; team_id teamID = team->id; @@ -1005,8 +1006,13 @@ thread_exit(void) } else death = NULL; - parentDeadSem = parent->dead_children.sem; - groupDeadSem = team->group->dead_child_sem; + // notify listeners that a new death entry is available + // 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); @@ -1021,11 +1027,6 @@ thread_exit(void) // delete the team if we're its main thread 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_team(team);