--- 2.2.13pre14/kernel/exit.c Tue Sep 28 18:32:39 1999 +++ /tmp/exit.c Fri Oct 1 20:16:57 1999 @@ -433,6 +433,13 @@ add_wait_queue(¤t->wait_chldexit,&wait); repeat: flag = 0; + + /* The interruptible state must be set before looking at the + childs. This because we want to catch any racy exit from + the childs as do_exit() may run under us. The following + read_lock will enforce SMP ordering at the CPU level. */ + current->state = TASK_INTERRUPTIBLE; + read_lock(&tasklist_lock); for (p = current->p_cptr ; p ; p = p->p_osptr) { if (pid>0) { @@ -499,13 +506,13 @@ retval = -ERESTARTSYS; if (signal_pending(current)) goto end_wait4; - current->state=TASK_INTERRUPTIBLE; schedule(); goto repeat; } retval = -ECHILD; end_wait4: remove_wait_queue(¤t->wait_chldexit,&wait); + current->state = TASK_RUNNING; return retval; }