diff options
author | Philip Guenthe <guenther@cvs.openbsd.org> | 2012-07-11 08:45:22 +0000 |
---|---|---|
committer | Philip Guenthe <guenther@cvs.openbsd.org> | 2012-07-11 08:45:22 +0000 |
commit | 68b55aeef1c40f85e1a766823f1736ef57e68e99 (patch) | |
tree | 6b64ac54cb92461f5dfe6c39681863268598a781 /sys/kern | |
parent | 3edf4186c45dbf9709b41c6f82b49c0472c432b0 (diff) |
exit1(EXIT_THREAD) needs to call single_thread_check() so that it
can be suspended and/or decrement pr->ps_singlecount if necessary.
With that added, the call the other direction needs to use its own
flag (EXIT_THREAD_NOCHECK) to avoid looping.
problem diagnosed from a hang naddy@ hit; ok kettenis@
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_exit.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_sig.c | 4 |
2 files changed, 5 insertions, 3 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 22700dffbec..bced9841c5b 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exit.c,v 1.116 2012/07/09 23:06:07 guenther Exp $ */ +/* $OpenBSD: kern_exit.c,v 1.117 2012/07/11 08:45:21 guenther Exp $ */ /* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */ /* @@ -138,6 +138,8 @@ exit1(struct proc *p, int rv, int flags) /* nope, multi-threaded */ if (flags == EXIT_NORMAL) single_thread_set(p, SINGLE_EXIT, 0); + else if (flags == EXIT_THREAD) + single_thread_check(p, 0); } if (flags == EXIT_NORMAL) { diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 06c26542e46..c47ef25b4c4 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.142 2012/06/06 04:47:43 guenther Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.143 2012/07/11 08:45:21 guenther Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -1722,7 +1722,7 @@ single_thread_check(struct proc *p, int deep) if (--pr->ps_singlecount == 0) wakeup(&pr->ps_singlecount); if (pr->ps_flags & PS_SINGLEEXIT) - exit1(p, 0, EXIT_THREAD); + exit1(p, 0, EXIT_THREAD_NOCHECK); /* not exiting and don't need to unwind, so suspend */ SCHED_LOCK(s); |