Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 139695
b: refs/heads/master
c: 5dfc80b
h: refs/heads/master
i:
  139693: 60f0e92
  139691: bee8c6b
  139687: 0488aae
  139679: f03449f
v: v3
  • Loading branch information
Oleg Nesterov authored and Linus Torvalds committed Apr 3, 2009
1 parent 385c602 commit 8c9d6a4
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 47 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 39c626ae47c469abdfd30c6e42eff884931380d6
refs/heads/master: 5dfc80be73dd0c212d2e6dd8dbf5afa07e680bbe
87 changes: 41 additions & 46 deletions trunk/kernel/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -726,46 +726,6 @@ static void exit_mm(struct task_struct * tsk)
mmput(mm);
}

/* Returns nonzero if the child should be released. */
static int reparent_thread(struct task_struct *p, struct task_struct *father)
{
int dead;

if (p->pdeath_signal)
/* We already hold the tasklist_lock here. */
group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p);

list_move_tail(&p->sibling, &p->real_parent->children);

if (task_detached(p))
return 0;
/* If this is a threaded reparent there is no need to
* notify anyone anything has happened.
*/
if (same_thread_group(p->real_parent, father))
return 0;

/* We don't want people slaying init. */
p->exit_signal = SIGCHLD;

/* If we'd notified the old parent about this child's death,
* also notify the new parent.
*/
dead = 0;
if (!p->ptrace &&
p->exit_state == EXIT_ZOMBIE && thread_group_empty(p)) {
do_notify_parent(p, p->exit_signal);
if (task_detached(p)) {
p->exit_state = EXIT_DEAD;
dead = 1;
}
}

kill_orphaned_pgrp(p, father);

return dead;
}

/*
* When we die, we re-parent all our children.
* Try to give them to another thread in our thread
Expand Down Expand Up @@ -805,10 +765,46 @@ static struct task_struct *find_new_reaper(struct task_struct *father)
return pid_ns->child_reaper;
}

/*
* 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,
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))
return;
/*
* If this is a threaded reparent there is no need to
* notify anyone anything has happened.
*/
if (same_thread_group(p->real_parent, father))
return;

/* We don't want people slaying init. */
p->exit_signal = SIGCHLD;

/* If it has exited notify the new parent about this child's death. */
if (!p->ptrace &&
p->exit_state == EXIT_ZOMBIE && thread_group_empty(p)) {
do_notify_parent(p, p->exit_signal);
if (task_detached(p)) {
p->exit_state = EXIT_DEAD;
list_move_tail(&p->sibling, dead);
}
}

kill_orphaned_pgrp(p, father);
}

static void forget_original_parent(struct task_struct *father)
{
struct task_struct *p, *n, *reaper;
LIST_HEAD(ptrace_dead);
LIST_HEAD(dead_children);

exit_ptrace(father);

Expand All @@ -821,15 +817,14 @@ static void forget_original_parent(struct task_struct *father)
BUG_ON(p->ptrace);
p->parent = p->real_parent;
}
if (reparent_thread(p, father))
list_add(&p->ptrace_entry, &ptrace_dead);;
reparent_thread(father, p, &dead_children);
}

write_unlock_irq(&tasklist_lock);

BUG_ON(!list_empty(&father->children));

list_for_each_entry_safe(p, n, &ptrace_dead, ptrace_entry) {
list_del_init(&p->ptrace_entry);
list_for_each_entry_safe(p, n, &dead_children, sibling) {
list_del_init(&p->sibling);
release_task(p);
}
}
Expand Down

0 comments on commit 8c9d6a4

Please sign in to comment.