summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2016-12-11 18:42:17 +0000
committerkib <kib@FreeBSD.org>2016-12-11 18:42:17 +0000
commitd1990f93b58ba5f976cd70f16e1086e2f356dec9 (patch)
tree2c7cb4d786d7215c957b865f757493616410ca68
parentaef01db5ff35254e0c5d197fb46f03e0e616e8bc (diff)
downloadFreeBSD-src-d1990f93b58ba5f976cd70f16e1086e2f356dec9.zip
FreeBSD-src-d1990f93b58ba5f976cd70f16e1086e2f356dec9.tar.gz
MFC r309539:
Restructure the code to handle reporting of non-exited processes from wait(2).
-rw-r--r--sys/kern/kern_exit.c113
1 files changed, 52 insertions, 61 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 3a20fb1..6063d33 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -1106,6 +1106,38 @@ kern_wait(struct thread *td, pid_t pid, int *status, int options,
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);
OpenPOWER on IntegriCloud