From: guenther Date: Thu, 17 Apr 2014 14:52:50 +0000 (+0000) Subject: Make sure the original thread is blocked until any other threads are X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=665e07d6cfe372a9cb7c136fce813ece1d8a4be8;p=openbsd Make sure the original thread is blocked until any other threads are completely detached from the process before letting it exit, so that sleeping in systrace_exit() doesn't reorder them and lead to a panic. Panic reported by Fabian Raetz (fabian.raetz (at) gmail.com) ok tedu@ --- diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index d559c72fae0..9f16c28216a 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exit.c,v 1.138 2014/03/30 21:54:48 guenther Exp $ */ +/* $OpenBSD: kern_exit.c,v 1.139 2014/04/17 14:52:50 guenther Exp $ */ /* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */ /* @@ -158,12 +158,10 @@ exit1(struct proc *p, int rv, int flags) TAILQ_REMOVE(&pr->ps_threads, p, p_thr_link); if ((p->p_flag & P_THREAD) == 0) { /* main thread gotta wait because it has the pid, et al */ - while (!TAILQ_EMPTY(&pr->ps_threads)) + while (pr->ps_refcnt > 1) tsleep(&pr->ps_threads, PUSER, "thrdeath", 0); if (pr->ps_flags & PS_PROFIL) stopprofclock(pr); - } else if (TAILQ_EMPTY(&pr->ps_threads)) { - wakeup(&pr->ps_threads); } rup = pr->ps_ru; @@ -356,7 +354,8 @@ exit1(struct proc *p, int rv, int flags) /* just a thread? detach it from its process */ if (p->p_flag & P_THREAD) { /* scheduler_wait_hook(pr->ps_mainproc, p); XXX */ - --pr->ps_refcnt; + if (--pr->ps_refcnt == 1) + wakeup(&pr->ps_threads); KASSERT(pr->ps_refcnt > 0); }