diff options
author | davidxu <davidxu@FreeBSD.org> | 2005-04-19 08:07:28 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2005-04-19 08:07:28 +0000 |
commit | 02615ff23a48b27178d931718a5a2e57e770175c (patch) | |
tree | b539120eeb397b4b6693bdc525a94d8ce07eec15 /sys/kern/kern_exit.c | |
parent | ed5a7da7983da8c0f3d644eedb48b7282b34e0dd (diff) | |
download | FreeBSD-src-02615ff23a48b27178d931718a5a2e57e770175c.zip FreeBSD-src-02615ff23a48b27178d931718a5a2e57e770175c.tar.gz |
Fix a race condition between kern_wait() and thread_stopped().
Problem is in kern_wait(), parent process steps through children list,
once a child process is skipped, and later even if the child is stopped,
parent process still sleeps in msleep(), the race happens if parent
masked SIGCHLD.
Submitted by : Peter Edwards peadar.edwards at gmail dot com
MFC after : 4 days
Diffstat (limited to 'sys/kern/kern_exit.c')
-rw-r--r-- | sys/kern/kern_exit.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 8b31e35..67ef152 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -743,7 +743,11 @@ loop: } PROC_LOCK(q); sx_xunlock(&proctree_lock); - error = msleep(q, &q->p_mtx, PWAIT | PCATCH, "wait", 0); + if (q->p_flag & P_STATCHILD) { + q->p_flag &= ~P_STATCHILD; + error = 0; + } else + error = msleep(q, &q->p_mtx, PWAIT | PCATCH, "wait", 0); PROC_UNLOCK(q); if (error) return (error); |