From 46cb5cfdd3ad5c8631447344267f9f5591ecb5e3 Mon Sep 17 00:00:00 2001
From: Ingo Weinhold <ingo_weinhold@gmx.de>
Date: Fri, 18 Jan 2008 23:39:13 +0000
Subject: [PATCH] When a main thread (i.e. a team) dies, we have to send the
 SIGCHLD to its parent while still holding the team spinlock. We were racing
 with wait_for_child(), since after the child invoked
 team_set_job_control_state(), the parent thread could continue as soon as the
 team spinlock was released. The SIGCHLD could thus arrive way later and
 interrupt another syscall. This could be reproduced with the compile_bench.sh
 script from time to time: When interrupted while waiting for the next
 subprocess, the gcc frontend would delete a still needed temporary file.

The whole thing is actually only a problem, because we don't support
automatic syscall restarts yet.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23625 a95241bf-73f2-0310-859d-f6bbb57e9c96
---
 src/system/kernel/thread.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp
index ab2051ebc1..694fae1e3e 100644
--- a/src/system/kernel/thread.cpp
+++ b/src/system/kernel/thread.cpp
@@ -1281,6 +1281,9 @@ thread_exit(void)
 				RELEASE_THREAD_LOCK();
 
 			team_remove_team(team, &freeGroup);
+
+			send_signal_etc(parentID, SIGCHLD,
+				SIGNAL_FLAG_TEAMS_LOCKED | B_DO_NOT_RESCHEDULE);
 		} else {
 			// The thread is not the main thread. We store a thread death
 			// entry for it, unless someone is already waiting it.
@@ -1327,7 +1330,6 @@ thread_exit(void)
 		if (death != NULL)
 			delete death;
 
-		send_signal_etc(parentID, SIGCHLD, B_DO_NOT_RESCHEDULE);
 		cachedDeathSem = -1;
 	}