From 3121f3948144b77af20a56ac2679e93e54b05b42 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 14 Jul 2010 01:20:58 +0000 Subject: [PATCH] thread_exit(): Postpone deleting the thread's user stack until after sending the thread's death notifications. The fixes issues where other threads depend on objects on its stack (particularly relevant for the main thread). Fixes #6315. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37509 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/thread.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index a985cd9a35..422895847c 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -1389,11 +1389,11 @@ thread_exit(void) // Cancel previously installed alarm timer, if any cancel_timer(&thread->alarm); - // delete the user stack area first, we won't need it anymore + // remember the user stack area -- we will delete it below + area_id userStackArea = -1; if (team->address_space != NULL && thread->user_stack_area >= 0) { - area_id area = thread->user_stack_area; + userStackArea = thread->user_stack_area; thread->user_stack_area = -1; - vm_delete_area(team->id, area, true); } struct job_control_entry *death = NULL; @@ -1588,6 +1588,20 @@ thread_exit(void) delete_sem(cachedExitSem); } + // delete the user stack, if this was a user thread + if (!deleteTeam && userStackArea >= 0) { + // We postponed deleting the user stack until now, since this way all + // notifications for the thread's death are out already and all other + // threads waiting for this thread's death and some object on its stack + // will wake up before we (try to) delete the stack area. Of most + // relevance is probably the case where this is the main thread and + // other threads use objects on its stack -- so we want them terminated + // first. + // When the team is deleted, all areas are deleted anyway, so we don't + // need to do that explicitly in that case. + vm_delete_area(teamID, userStackArea, true); + } + // notify the debugger if (teamID != team_get_kernel_team_id()) user_debug_thread_deleted(teamID, thread->id);