|
@@ -68,10 +68,10 @@ static void __unhash_process(struct task_struct *p)
|
|
|
detach_pid(p, PIDTYPE_SID);
|
|
|
|
|
|
list_del_rcu(&p->tasks);
|
|
|
+ list_del_init(&p->sibling);
|
|
|
__get_cpu_var(process_counts)--;
|
|
|
}
|
|
|
list_del_rcu(&p->thread_group);
|
|
|
- list_del_init(&p->sibling);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -736,12 +736,9 @@ static struct task_struct *find_new_reaper(struct task_struct *father)
|
|
|
/*
|
|
|
* Any that need to be release_task'd are put on the @dead list.
|
|
|
*/
|
|
|
-static void reparent_thread(struct task_struct *father, struct task_struct *p,
|
|
|
+static void reparent_leader(struct task_struct *father, struct task_struct *p,
|
|
|
struct list_head *dead)
|
|
|
{
|
|
|
- if (p->pdeath_signal)
|
|
|
- group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p);
|
|
|
-
|
|
|
list_move_tail(&p->sibling, &p->real_parent->children);
|
|
|
|
|
|
if (task_detached(p))
|
|
@@ -780,12 +777,18 @@ static void forget_original_parent(struct task_struct *father)
|
|
|
reaper = find_new_reaper(father);
|
|
|
|
|
|
list_for_each_entry_safe(p, n, &father->children, sibling) {
|
|
|
- p->real_parent = reaper;
|
|
|
- if (p->parent == father) {
|
|
|
- BUG_ON(task_ptrace(p));
|
|
|
- p->parent = p->real_parent;
|
|
|
- }
|
|
|
- reparent_thread(father, p, &dead_children);
|
|
|
+ struct task_struct *t = p;
|
|
|
+ do {
|
|
|
+ t->real_parent = reaper;
|
|
|
+ if (t->parent == father) {
|
|
|
+ BUG_ON(task_ptrace(t));
|
|
|
+ t->parent = t->real_parent;
|
|
|
+ }
|
|
|
+ if (t->pdeath_signal)
|
|
|
+ group_send_sig_info(t->pdeath_signal,
|
|
|
+ SEND_SIG_NOINFO, t);
|
|
|
+ } while_each_thread(p, t);
|
|
|
+ reparent_leader(father, p, &dead_children);
|
|
|
}
|
|
|
write_unlock_irq(&tasklist_lock);
|
|
|
|
|
@@ -1551,14 +1554,9 @@ static int do_wait_thread(struct wait_opts *wo, struct task_struct *tsk)
|
|
|
struct task_struct *p;
|
|
|
|
|
|
list_for_each_entry(p, &tsk->children, sibling) {
|
|
|
- /*
|
|
|
- * Do not consider detached threads.
|
|
|
- */
|
|
|
- if (!task_detached(p)) {
|
|
|
- int ret = wait_consider_task(wo, 0, p);
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
- }
|
|
|
+ int ret = wait_consider_task(wo, 0, p);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
return 0;
|