summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2005-12-13 07:38:41 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2005-12-13 07:38:41 +0000
commit1fabae1a9a9ca0a8920d56ceb0f214eda4c73d0f (patch)
treeb6323ab451d83827ab0021d8353d150c349fa79b /sys
parent0c56c75496081e7de984127c2c0b3c32ba63e974 (diff)
make exiting actually work when a thread receives a signal.
previously, the child and parent would deadlock in the kernel and be unable to exit. help with diagnosis from art@.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_exit.c16
1 files changed, 5 insertions, 11 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 7034dcbd8fc..fbcfb3e7779 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_exit.c,v 1.57 2005/12/03 18:09:08 tedu Exp $ */
+/* $OpenBSD: kern_exit.c,v 1.58 2005/12/13 07:38:40 tedu Exp $ */
/* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */
/*
@@ -126,36 +126,30 @@ exit1(struct proc *p, int rv, int flags)
*/
if (flags == EXIT_NORMAL && p != p->p_thrparent &&
(p->p_thrparent->p_flag & P_WEXIT) == 0) {
- printf("thread exiting normally %d\n", p->p_pid);
/*
* we are one of the threads. we SIGKILL the parent,
- * then wait for it to kill us back. as soon as we return,
- * we'll exit again.
+ * it will wake us up again, then we proceed.
*/
p->p_thrparent->p_flag |= P_IGNEXITRV;
p->p_thrparent->p_xstat = rv;
psignal(p->p_thrparent, SIGKILL);
- tsleep(&p->p_thrparent->p_thrchildren, PUSER | PCATCH, "dying",
- 0);
- printf("thread got sig %d\n", p->p_pid);
- return;
+ tsleep(&p->p_thrparent->p_thrchildren, PUSER, "thrdying", 0);
} else if (p == p->p_thrparent) {
p->p_flag |= P_WEXIT;
if (flags == EXIT_NORMAL) {
q = LIST_FIRST(&p->p_thrchildren);
- for (; q != 0; q = nq) {
+ for (; q != NULL; q = nq) {
nq = LIST_NEXT(q, p_thrsib);
q->p_flag |= P_IGNEXITRV;
q->p_xstat = rv;
- printf("parent killing child %d\n", q->p_pid);
psignal(q, SIGKILL);
}
}
+ wakeup(&p->p_thrchildren);
while (!LIST_EMPTY(&p->p_thrchildren))
tsleep(&p->p_thrchildren, PUSER, "thrdeath", 0);
}
-
if (p->p_flag & P_PROFIL)
stopprofclock(p);
p->p_ru = pool_get(&rusage_pool, PR_WAITOK);