Date: Sun, 11 Dec 2016 18:42:17 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r309853 - stable/11/sys/kern Message-ID: <201612111842.uBBIgHw1081810@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Sun Dec 11 18:42:17 2016 New Revision: 309853 URL: https://svnweb.freebsd.org/changeset/base/309853 Log: MFC r309539: Restructure the code to handle reporting of non-exited processes from wait(2). Modified: stable/11/sys/kern/kern_exit.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/kern/kern_exit.c ============================================================================== --- stable/11/sys/kern/kern_exit.c Sun Dec 11 17:15:25 2016 (r309852) +++ stable/11/sys/kern/kern_exit.c Sun Dec 11 18:42:17 2016 (r309853) @@ -1106,6 +1106,38 @@ kern_wait(struct thread *td, pid_t pid, return (ret); } +static void +report_alive_proc(struct thread *td, struct proc *p, siginfo_t *siginfo, + int *status, int options, int si_code) +{ + bool cont; + + PROC_LOCK_ASSERT(p, MA_OWNED); + sx_assert(&proctree_lock, SA_XLOCKED); + MPASS(si_code == CLD_TRAPPED || si_code == CLD_STOPPED || + si_code == CLD_CONTINUED); + + cont = si_code == CLD_CONTINUED; + if ((options & WNOWAIT) == 0) { + if (cont) + p->p_flag &= ~P_CONTINUED; + else + p->p_flag |= P_WAITED; + PROC_LOCK(td->td_proc); + sigqueue_take(p->p_ksi); + PROC_UNLOCK(td->td_proc); + } + sx_xunlock(&proctree_lock); + if (siginfo != NULL) { + siginfo->si_code = si_code; + siginfo->si_status = cont ? SIGCONT : p->p_xsig; + } + if (status != NULL) + *status = cont ? SIGCONT : W_STOPCODE(p->p_xsig); + PROC_UNLOCK(p); + td->td_retval[0] = p->p_pid; +} + int kern_wait6(struct thread *td, idtype_t idtype, id_t id, int *status, int options, struct __wrusage *wrusage, siginfo_t *siginfo) @@ -1163,82 +1195,41 @@ loop: } PROC_LOCK(p); - PROC_SLOCK(p); + + if ((options & (WTRAPPED | WUNTRACED)) != 0) + PROC_SLOCK(p); if ((options & WTRAPPED) != 0 && (p->p_flag & P_TRACED) != 0 && (p->p_flag & (P_STOPPED_TRACE | P_STOPPED_SIG)) != 0 && - (p->p_suspcount == p->p_numthreads) && - ((p->p_flag & P_WAITED) == 0)) { + p->p_suspcount == p->p_numthreads && + (p->p_flag & P_WAITED) == 0) { PROC_SUNLOCK(p); - if ((options & WNOWAIT) == 0) - p->p_flag |= P_WAITED; - sx_xunlock(&proctree_lock); - - if (status != NULL) - *status = W_STOPCODE(p->p_xsig); - if (siginfo != NULL) { - siginfo->si_status = p->p_xsig; - siginfo->si_code = CLD_TRAPPED; - } - if ((options & WNOWAIT) == 0) { - PROC_LOCK(q); - sigqueue_take(p->p_ksi); - PROC_UNLOCK(q); - } - CTR4(KTR_PTRACE, - "wait: returning trapped pid %d status %#x (xstat %d) xthread %d", + "wait: returning trapped pid %d status %#x " + "(xstat %d) xthread %d", p->p_pid, W_STOPCODE(p->p_xsig), p->p_xsig, - p->p_xthread != NULL ? p->p_xthread->td_tid : -1); - PROC_UNLOCK(p); - td->td_retval[0] = pid; + p->p_xthread != NULL ? + p->p_xthread->td_tid : -1); + report_alive_proc(td, p, siginfo, status, options, + CLD_TRAPPED); return (0); - } + } if ((options & WUNTRACED) != 0 && (p->p_flag & P_STOPPED_SIG) != 0 && - (p->p_suspcount == p->p_numthreads) && - ((p->p_flag & P_WAITED) == 0)) { + p->p_suspcount == p->p_numthreads && + (p->p_flag & P_WAITED) == 0) { PROC_SUNLOCK(p); - if ((options & WNOWAIT) == 0) - p->p_flag |= P_WAITED; - sx_xunlock(&proctree_lock); - - if (status != NULL) - *status = W_STOPCODE(p->p_xsig); - if (siginfo != NULL) { - siginfo->si_status = p->p_xsig; - siginfo->si_code = CLD_STOPPED; - } - if ((options & WNOWAIT) == 0) { - PROC_LOCK(q); - sigqueue_take(p->p_ksi); - PROC_UNLOCK(q); - } - - PROC_UNLOCK(p); - td->td_retval[0] = pid; + report_alive_proc(td, p, siginfo, status, options, + CLD_STOPPED); return (0); } - PROC_SUNLOCK(p); + if ((options & (WTRAPPED | WUNTRACED)) != 0) + PROC_SUNLOCK(p); if ((options & WCONTINUED) != 0 && (p->p_flag & P_CONTINUED) != 0) { - sx_xunlock(&proctree_lock); - if ((options & WNOWAIT) == 0) { - p->p_flag &= ~P_CONTINUED; - PROC_LOCK(q); - sigqueue_take(p->p_ksi); - PROC_UNLOCK(q); - } - PROC_UNLOCK(p); - - if (status != NULL) - *status = SIGCONT; - if (siginfo != NULL) { - siginfo->si_status = SIGCONT; - siginfo->si_code = CLD_CONTINUED; - } - td->td_retval[0] = pid; + report_alive_proc(td, p, siginfo, status, options, + CLD_CONTINUED); return (0); } PROC_UNLOCK(p);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201612111842.uBBIgHw1081810>