summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2013-06-01 16:04:47 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2013-06-01 16:04:47 +0000
commit279e7c0ae74ae79649ceb00ad0b56a345408b41a (patch)
tree7d8317711cf9bf485768fd3c77f785011b174a84 /sys
parent5c24f105c6ffdde7290d6d1ed666b7362877f35a (diff)
As found by kurt, there's a twisty race between exit1 and fork1
with threaded processes. Fix this by checking for an attempt to go single threaded in fork1 and account for the new thread as well. ok espie guenther kurt
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_fork.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index fbe7dcf19d4..dd4de7f0c9b 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_fork.c,v 1.146 2013/04/06 03:44:34 tedu Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.147 2013/06/01 16:04:46 tedu Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@@ -325,6 +325,14 @@ fork1(struct proc *curp, int exitsig, int flags, void *stack, pid_t *tidptr,
p->p_p = pr = curpr;
TAILQ_INSERT_TAIL(&pr->ps_threads, p, p_thr_link);
pr->ps_refcnt++;
+ /*
+ * if somebody else wants to take us to single threaded mode,
+ * count ourselves in.
+ */
+ if (pr->ps_single) {
+ curpr->ps_singlecount++;
+ atomic_setbits_int(&p->p_flag, P_SUSPSINGLE);
+ }
} else {
process_new(p, curpr);
pr = p->p_p;