summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2012-07-11 08:45:22 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2012-07-11 08:45:22 +0000
commit68b55aeef1c40f85e1a766823f1736ef57e68e99 (patch)
tree6b64ac54cb92461f5dfe6c39681863268598a781
parent3edf4186c45dbf9709b41c6f82b49c0472c432b0 (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@
-rw-r--r--sys/kern/kern_exit.c4
-rw-r--r--sys/kern/kern_sig.c4
-rw-r--r--sys/sys/proc.h7
3 files changed, 9 insertions, 6 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);
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index b95615aa816..d192883430b 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.159 2012/06/13 22:47:40 ariane Exp $ */
+/* $OpenBSD: proc.h,v 1.160 2012/07/11 08:45:21 guenther Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -480,8 +480,9 @@ struct uidinfo *uid_find(uid_t);
#define FORK_PTRACE 0x00000400
#define FORK_THREAD 0x00000800
-#define EXIT_NORMAL 0x00000001
-#define EXIT_THREAD 0x00000002
+#define EXIT_NORMAL 0x00000001
+#define EXIT_THREAD 0x00000002
+#define EXIT_THREAD_NOCHECK 0x00000003
#define PIDHASH(pid) (&pidhashtbl[(pid) & pidhash])
extern LIST_HEAD(pidhashhead, proc) *pidhashtbl;