]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/kern_exit.c
xnu-201.14.tar.gz
[apple/xnu.git] / bsd / kern / kern_exit.c
index ffb3efdcfa3e24cb50d9b30aff48934a12458968..84c51a09c7dbb7db0435ce8c41eda14f8ebdf9a5 100644 (file)
@@ -204,7 +204,6 @@ proc_prepareexit(struct proc *p)
        thread_t self = current_thread();
        thread_act_t th_act_self = current_act();
 
-
        /*
         * Remove proc from allproc queue and from pidhash chain.
         * Need to do this before we do anything that can block.
@@ -227,7 +226,6 @@ proc_prepareexit(struct proc *p)
        ut = get_bsdthread_info(th_act_self);
        ut->uu_sig = 0;
        untimeout(realitexpire, (caddr_t)p);
-
 }
 
 void 
@@ -238,7 +236,6 @@ proc_exit(struct proc *p)
        thread_act_t th_act_self = current_act();
        struct task *task = p->task;
        register int i,s;
-       struct uthread *ut;
        boolean_t funnel_state;
 
        /* This can happen if thread_terminate of the single thread
@@ -340,7 +337,6 @@ proc_exit(struct proc *p)
                }
        }
 
-
        /*
         * Save exit status and final rusage info, adding in child rusage
         * info and self times.
@@ -376,7 +372,6 @@ proc_exit(struct proc *p)
                timeradd(&st,&p->p_ru->ru_stime,&p->p_ru->ru_stime);
        }
 
-
        ruadd(p->p_ru, &p->p_stats->p_cru);
 
        /*
@@ -464,7 +459,6 @@ wait4(p, uap, retval)
        struct wait4_args *uap;
        int *retval;
 {
-
        return (wait1(p, uap, retval, 0));
 }
 
@@ -499,21 +493,16 @@ owait3(p, uap, retval)
 int
 wait1continue(result)
 {
-  void *vt;
-  thread_act_t thread;
-  struct uthread *ut;
-  int *retval;
-  struct proc *p;
-
-       p = current_proc();
-       p->p_flag &= ~P_WAITING;
+       void *vt;
+       thread_act_t thread;
+       int *retval;
+       struct proc *p;
 
-      if (result != 0) {
-         return(result);
-       }
+       if (result)
+               return(result);
 
-    thread = current_act();
-       ut = get_bsdthread_info(thread);
+       p = current_proc();
+       thread = current_act();
        vt = get_bsduthreadarg(thread);
        retval = get_bsduthreadrval(thread);
        wait1((struct proc *)p, (struct wait4_args *)vt, retval, 0);
@@ -532,15 +521,7 @@ wait1(q, uap, retval, compat)
        register struct proc *p, *t;
        int status, error;
 
-
-#if 0
-       /* since we are funneled we don't need to do this atomically, yet */
-       if (q->p_flag & P_WAITING) {
-         return(EINVAL);
-       }
-       q->p_flag |= P_WAITING;   /* only allow single thread to wait() */
-#endif
-
+retry:
        if (uap->pid == 0)
                uap->pid = -q->p_pgid;
 
@@ -552,6 +533,12 @@ loop:
                    p->p_pgid != -(uap->pid))
                        continue;
                nfound++;
+               if (p->p_flag & P_WAITING) {
+                       (void)tsleep(&p->p_stat, PWAIT, "waitcoll", 0);
+                       goto loop;
+               }
+               p->p_flag |= P_WAITING;   /* only allow single thread to wait() */
+
                if (p->p_stat == SZOMB) {
                        retval[0] = p->p_pid;
 #if COMPAT_43
@@ -564,7 +551,8 @@ loop:
                                if (error = copyout((caddr_t)&status,
                                    (caddr_t)uap->status,
                                                    sizeof(status))) {
-                                       q->p_flag &= ~P_WAITING;
+                                       p->p_flag &= ~P_WAITING;
+                                       wakeup(&p->p_stat);
                                        return (error);
                                }
                        }
@@ -572,7 +560,8 @@ loop:
                            (error = copyout((caddr_t)p->p_ru,
                            (caddr_t)uap->rusage,
                                             sizeof (struct rusage)))) {
-                                       q->p_flag &= ~P_WAITING;
+                               p->p_flag &= ~P_WAITING;
+                               wakeup(&p->p_stat);
                                return (error);
                        }
                        /*
@@ -584,7 +573,8 @@ loop:
                                proc_reparent(p, t);
                                psignal(t, SIGCHLD);
                                wakeup((caddr_t)t);
-                                       q->p_flag &= ~P_WAITING;
+                               p->p_flag &= ~P_WAITING;
+                               wakeup(&p->p_stat);
                                return (0);
                        }
                        p->p_xstat = 0;
@@ -630,9 +620,10 @@ loop:
                        leavepgrp(p);
                        LIST_REMOVE(p, p_list); /* off zombproc */
                        LIST_REMOVE(p, p_sibling);
+                       p->p_flag &= ~P_WAITING;
                        FREE_ZONE(p, sizeof *p, M_PROC);
                        nprocs--;
-                                       q->p_flag &= ~P_WAITING;
+                       wakeup(&p->p_stat);
                        return (0);
                }
                if (p->p_stat == SSTOP && (p->p_flag & P_WAITED) == 0 &&
@@ -652,24 +643,24 @@ loop:
                                    sizeof(status));
                        } else
                                error = 0;
-                                       q->p_flag &= ~P_WAITING;
+                       p->p_flag &= ~P_WAITING;
+                       wakeup(&p->p_stat);
                        return (error);
                }
+               p->p_flag &= ~P_WAITING;
+               wakeup(&p->p_stat);
        }
-       if (nfound == 0) {
-                                       q->p_flag &= ~P_WAITING;
+       if (nfound == 0)
                return (ECHILD);
-       }
+
        if (uap->options & WNOHANG) {
                retval[0] = 0;
-                                       q->p_flag &= ~P_WAITING;
                return (0);
        }
 
-       if (error = tsleep0((caddr_t)q, PWAIT | PCATCH, "wait", 0, wait1continue)) {
-                                       q->p_flag &= ~P_WAITING;
+       if (error = tsleep0((caddr_t)q, PWAIT | PCATCH, "wait", 0, wait1continue))
                return (error);
-       }
+
        goto loop;
 }
 
@@ -690,13 +681,13 @@ proc_reparent(child, parent)
        child->p_pptr = parent;
 }
 
-kern_return_t
-init_process(void)
 /*
  *     Make the current process an "init" process, meaning
  *     that it doesn't have a parent, and that it won't be
  *     gunned down by kill(-1, 0).
  */
+kern_return_t
+init_process(void)
 {
        register struct proc *p = current_proc();
 
@@ -729,6 +720,7 @@ process_terminate_self(void)
                /*NOTREACHED*/
        }
 }
+
 /*
  * Exit: deallocate address space and other resources, change proc state
  * to zombie, and unlink proc from allproc and parent's lists.  Save exit
@@ -805,7 +797,6 @@ panic("init died\nState at Last Exception:\n\n%s", init_task_failure_data);
        vproc_exit(p);
 }
 
-
 void 
 vproc_exit(struct proc *p)
 {
@@ -814,7 +805,6 @@ vproc_exit(struct proc *p)
        thread_act_t th_act_self = current_act();
        struct task *task = p->task;
        register int i,s;
-       struct uthread *ut;
        boolean_t funnel_state;
 
        MALLOC_ZONE(p->p_ru, struct rusage *,
@@ -874,7 +864,6 @@ vproc_exit(struct proc *p)
                vrele(p->p_tracep);
 #endif
 
-
        q = p->p_children.lh_first;
        if (q)          /* only need this if any child is S_ZOMB */
                wakeup((caddr_t) initproc);
@@ -904,7 +893,6 @@ vproc_exit(struct proc *p)
                }
        }
 
-
        /*
         * Save exit status and final rusage info, adding in child rusage
         * info and self times.
@@ -991,6 +979,4 @@ vproc_exit(struct proc *p)
 
        /* and now wakeup the parent */
        wakeup((caddr_t)p->p_pptr);
-
 }
-