summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_exit.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_exit.c')
-rw-r--r--sys/kern/kern_exit.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 5785e0b..0738e69 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -175,7 +175,29 @@ retry:
*/
}
+ /*
+ * Wakeup anyone in procfs' PIOCWAIT. They should have a hold
+ * on our vmspace, so we should block below until they have
+ * released their reference to us. Note that if they have
+ * requested S_EXIT stops we will block here until they ack
+ * via PIOCCONT.
+ */
+ _STOPEVENT(p, S_EXIT, rv);
+
+ /*
+ * Note that we are exiting and do another wakeup of anyone in
+ * PIOCWAIT in case they aren't listening for S_EXIT stops or
+ * decided to wait again after we told them we are exiting.
+ */
p->p_flag |= P_WEXIT;
+ wakeup(&p->p_stype);
+
+ /*
+ * Wait for any processes that have a hold on our vmspace to
+ * release their reference.
+ */
+ while (p->p_lock > 0)
+ msleep(&p->p_lock, &p->p_mtx, PWAIT, "exithold", 0);
PROC_LOCK(p->p_pptr);
sigqueue_take(p->p_ksi);
@@ -209,11 +231,6 @@ retry:
mtx_unlock(&ppeers_lock);
}
- PROC_LOCK(p);
- _STOPEVENT(p, S_EXIT, rv);
- wakeup(&p->p_stype); /* Wakeup anyone in procfs' PIOCWAIT */
- PROC_UNLOCK(p);
-
/*
* Check if any loadable modules need anything done at process exit.
* E.g. SYSV IPC stuff
OpenPOWER on IntegriCloud