- while (q = p->p_children.lh_first) {
- proc_reparent(q, initproc);
- /*
- * Traced processes are killed
- * since their existence means someone is messing up.
- */
- if (q->p_flag & P_TRACED) {
- q->p_flag &= ~P_TRACED;
- if (q->sigwait_thread) {
- /*
- * The sigwait_thread could be stopped at a
- * breakpoint. Wake it up to kill.
- * Need to do this as it could be a thread which is not
- * the first thread in the task. So any attempts to kill
- * the process would result into a deadlock on q->sigwait.
- */
- thread_resume((thread_t)q->sigwait_thread);
- clear_wait(q->sigwait_thread, THREAD_INTERRUPTED);
- threadsignal((thread_t)q->sigwait_thread, SIGKILL, 0);
+ /* wait till parentrefs are dropped and grant no more */
+ proc_childdrainstart(p);
+ while ((q = p->p_children.lh_first) != NULL) {
+ q->p_listflag |= P_LIST_DEADPARENT;
+ if (q->p_stat == SZOMB) {
+ if (p != q->p_pptr)
+ panic("parent child linkage broken");
+ /* check for sysctl zomb lookup */
+ while ((q->p_listflag & P_LIST_WAITING) == P_LIST_WAITING) {
+ msleep(&q->p_stat, proc_list_mlock, PWAIT, "waitcoll", 0);
+ }
+ q->p_listflag |= P_LIST_WAITING;
+ /*
+ * This is a named reference and it is not granted
+ * if the reap is already in progress. So we get
+ * the reference here exclusively and their can be
+ * no waiters. So there is no need for a wakeup
+ * after we are done. AlsO the reap frees the structure
+ * and the proc struct cannot be used for wakeups as well.
+ * It is safe to use q here as this is system reap
+ */
+ (void)reap_child_locked(p, q, 1, 1, 0);
+ } else {
+ proc_reparentlocked(q, initproc, 0, 1);
+ /*
+ * Traced processes are killed
+ * since their existence means someone is messing up.
+ */
+ if (q->p_lflag & P_LTRACED) {
+ proc_list_unlock();
+ proc_lock(q);
+ q->p_lflag &= ~P_LTRACED;
+ if (q->sigwait_thread) {
+ proc_unlock(q);
+ /*
+ * The sigwait_thread could be stopped at a
+ * breakpoint. Wake it up to kill.
+ * Need to do this as it could be a thread which is not
+ * the first thread in the task. So any attempts to kill
+ * the process would result into a deadlock on q->sigwait.
+ */
+ thread_resume((thread_t)q->sigwait_thread);
+ clear_wait(q->sigwait_thread, THREAD_INTERRUPTED);
+ threadsignal((thread_t)q->sigwait_thread, SIGKILL, 0);
+ } else
+ proc_unlock(q);
+ psignal(q, SIGKILL);
+ proc_list_lock();