patch-2.2.14 linux/kernel/exit.c
Next file: linux/kernel/kmod.c
Previous file: linux/kernel/dma.c
Back to the patch index
Back to the overall index
- Lines: 51
- Date:
Tue Jan 4 10:12:25 2000
- Orig file:
v2.2.13/linux/kernel/exit.c
- Orig date:
Tue Jan 4 11:10:42 2000
diff -u --recursive --new-file v2.2.13/linux/kernel/exit.c linux/kernel/exit.c
@@ -232,18 +232,17 @@
static inline void __exit_sighand(struct task_struct *tsk)
{
struct signal_struct * sig = tsk->sig;
+ unsigned long flags;
+ spin_lock_irqsave(&tsk->sigmask_lock, flags);
if (sig) {
- unsigned long flags;
-
- spin_lock_irqsave(&tsk->sigmask_lock, flags);
tsk->sig = NULL;
- spin_unlock_irqrestore(&tsk->sigmask_lock, flags);
if (atomic_dec_and_test(&sig->count))
kfree(sig);
}
flush_signals(tsk);
+ spin_unlock_irqrestore(&tsk->sigmask_lock, flags);
}
void exit_sighand(struct task_struct *tsk)
@@ -444,6 +443,13 @@
add_wait_queue(¤t->wait_chldexit,&wait);
repeat:
flag = 0;
+
+ /* The interruptible state must be set before looking at the
+ children. This because we want to catch any racy exit from
+ the children 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) {
@@ -510,13 +516,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;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)