svn commit: r309853 - stable/11/sys/kern
Konstantin Belousov
kib at FreeBSD.org
Sun Dec 11 18:42:18 UTC 2016
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);
More information about the svn-src-all
mailing list