aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@tv-sign.ru>2008-03-02 13:44:44 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-03-03 17:53:16 -0500
commit821c7de7194e77afee1a69d50830a329a6d9af9f (patch)
tree6755cb5f57822c142b228ad8ca817c18b8f31884
parent05e83df624fe682bb8571cdb2c6d5284a99c3066 (diff)
exit_notify: fix kill_orphaned_pgrp() usage with mt exit
1. exit_notify() always calls kill_orphaned_pgrp(). This is wrong, we should do this only when the whole process exits. 2. exit_notify() uses "current" as "ignored_task", obviously wrong. Use ->group_leader instead. Test case: void hup(int sig) { printf("HUP received\n"); } void *tfunc(void *arg) { sleep(2); printf("sub-thread exited\n"); return NULL; } int main(int argc, char *argv[]) { if (!fork()) { signal(SIGHUP, hup); kill(getpid(), SIGSTOP); exit(0); } pthread_t thr; pthread_create(&thr, NULL, tfunc, NULL); sleep(1); printf("main thread exited\n"); syscall(__NR_exit, 0); return 0; } output: main thread exited HUP received Hangup With this patch the output is: main thread exited sub-thread exited HUP received Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--kernel/exit.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 41c1edace97a..cd20bf07e9e3 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -750,7 +750,7 @@ static void forget_original_parent(struct task_struct *father)
750 * Send signals to all our closest relatives so that they know 750 * Send signals to all our closest relatives so that they know
751 * to properly mourn us.. 751 * to properly mourn us..
752 */ 752 */
753static void exit_notify(struct task_struct *tsk) 753static void exit_notify(struct task_struct *tsk, int group_dead)
754{ 754{
755 int state; 755 int state;
756 756
@@ -766,7 +766,8 @@ static void exit_notify(struct task_struct *tsk)
766 exit_task_namespaces(tsk); 766 exit_task_namespaces(tsk);
767 767
768 write_lock_irq(&tasklist_lock); 768 write_lock_irq(&tasklist_lock);
769 kill_orphaned_pgrp(tsk, NULL); 769 if (group_dead)
770 kill_orphaned_pgrp(tsk->group_leader, NULL);
770 771
771 /* Let father know we died 772 /* Let father know we died
772 * 773 *
@@ -981,7 +982,7 @@ NORET_TYPE void do_exit(long code)
981 module_put(tsk->binfmt->module); 982 module_put(tsk->binfmt->module);
982 983
983 proc_exit_connector(tsk); 984 proc_exit_connector(tsk);
984 exit_notify(tsk); 985 exit_notify(tsk, group_dead);
985#ifdef CONFIG_NUMA 986#ifdef CONFIG_NUMA
986 mpol_free(tsk->mempolicy); 987 mpol_free(tsk->mempolicy);
987 tsk->mempolicy = NULL; 988 tsk->mempolicy = NULL;