diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2013-06-01 16:04:47 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2013-06-01 16:04:47 +0000 |
commit | 279e7c0ae74ae79649ceb00ad0b56a345408b41a (patch) | |
tree | 7d8317711cf9bf485768fd3c77f785011b174a84 /sys | |
parent | 5c24f105c6ffdde7290d6d1ed666b7362877f35a (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.c | 10 |
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; |