summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2005-04-19 08:07:28 +0000
committerdavidxu <davidxu@FreeBSD.org>2005-04-19 08:07:28 +0000
commit02615ff23a48b27178d931718a5a2e57e770175c (patch)
treeb539120eeb397b4b6693bdc525a94d8ce07eec15 /sys
parented5a7da7983da8c0f3d644eedb48b7282b34e0dd (diff)
downloadFreeBSD-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')
-rw-r--r--sys/kern/kern_exit.c6
-rw-r--r--sys/sys/proc.h1
2 files changed, 6 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);
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index b7703d2..5b048bd 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -638,6 +638,7 @@ struct proc {
#define P_JAILED 0x1000000 /* Process is in jail. */
#define P_INEXEC 0x4000000 /* Process is in execve(). */
+#define P_STATCHILD 0x8000000 /* Child process stopped or exited. */
#define P_STOPPED (P_STOPPED_SIG|P_STOPPED_SINGLE|P_STOPPED_TRACE)
#define P_SHOULDSTOP(p) ((p)->p_flag & P_STOPPED)
OpenPOWER on IntegriCloud