Oops, forgot to update this file.
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
This commit is contained in:
parent
95992d56f5
commit
407948a530
@ -85,7 +85,6 @@ static char *expand_name(const char *, uid_t, pid_t);
|
||||
static int killpg1(struct thread *td, int sig, int pgid, int all);
|
||||
static int issignal(struct thread *p);
|
||||
static int sigprop(int sig);
|
||||
static void stop(struct proc *);
|
||||
static void tdsigwakeup(struct thread *td, int sig, sig_t action);
|
||||
static int filt_sigattach(struct knote *kn);
|
||||
static void filt_sigdetach(struct knote *kn);
|
||||
@ -2249,21 +2248,6 @@ issignal(td)
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the argument process into the stopped state and notify the parent
|
||||
* via wakeup. Signals are handled elsewhere. The process must not be
|
||||
* on the run queue. Must be called with the proc p locked.
|
||||
*/
|
||||
static void
|
||||
stop(struct proc *p)
|
||||
{
|
||||
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
p->p_flag |= P_STOPPED_SIG;
|
||||
p->p_flag &= ~P_WAITED;
|
||||
wakeup(p->p_pptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
@ -2281,8 +2265,16 @@ thread_stopped(struct proc *p)
|
||||
n++;
|
||||
if ((p->p_flag & P_STOPPED_SIG) && (n == p->p_numthreads)) {
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
stop(p);
|
||||
p->p_flag &= ~P_WAITED;
|
||||
PROC_LOCK(p->p_pptr);
|
||||
/*
|
||||
* Wake up parent sleeping in kern_wait(), also send
|
||||
* SIGCHLD to parent, but SIGCHLD does not guarantee
|
||||
* that parent will awake, because parent may masked
|
||||
* the signal.
|
||||
*/
|
||||
p->p_pptr->p_flag |= P_STATCHILD;
|
||||
wakeup(p->p_pptr);
|
||||
ps = p->p_pptr->p_sigacts;
|
||||
mtx_lock(&ps->ps_mtx);
|
||||
if ((ps->ps_flag & PS_NOCLDSTOP) == 0) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user