diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2005-12-13 07:38:41 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2005-12-13 07:38:41 +0000 |
commit | 1fabae1a9a9ca0a8920d56ceb0f214eda4c73d0f (patch) | |
tree | b6323ab451d83827ab0021d8353d150c349fa79b /sys/kern | |
parent | 0c56c75496081e7de984127c2c0b3c32ba63e974 (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/kern')
-rw-r--r-- | sys/kern/kern_exit.c | 16 |
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); |