Author: bonefish Date: 2011-05-23 14:47:32 +0200 (Mon, 23 May 2011) New Revision: 41679 Changeset: https://dev.haiku-os.org/changeset/41679 Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp Log: process_group_has_stopped_processes(): Check the team's job control entry rather than its main thread's state. Besides this being the more accurate notion of the process being stopped, it avoids a race condition with handle_signals(). Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp 2011-05-23 12:36:43 UTC (rev 41678) +++ haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp 2011-05-23 12:47:32 UTC (rev 41679) @@ -2396,23 +2396,19 @@ static bool process_group_has_stopped_processes(ProcessGroup* group) { - // Grab the scheduler spinlock -- it guards the Thread::state field, - // which we check in the loop. - InterruptsSpinLocker schedulerLocker(gSchedulerLock); - Team* team = group->teams; while (team != NULL) { - // Note: The following check is safe, since team won't go away as long - // as the group is locked and since the team's main thread removes the - // team from its process group in thread_exit() we can also be sure that - // the main thread object does still live (the thread might already have - // been transferred to the kernel team, but team->main_thread still - // points to it). If the team is still in the process of being created, - // it might not have a main thread yet. - Thread* mainThread = team->main_thread; - if (mainThread != NULL && mainThread->state == B_THREAD_SUSPENDED) + // the parent team's lock guards the job control entry -- acquire it + team->LockTeamAndParent(false); + + if (team->job_control_entry != NULL + && team->job_control_entry->state == JOB_CONTROL_STATE_STOPPED) { + team->UnlockTeamAndParent(); return true; + } + team->UnlockTeamAndParent(); + team = team->group_next; }