diff options
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 17 |
1 files changed, 4 insertions, 13 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 190a4cdcdb4d..9ee229ea97e4 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -1140,12 +1140,6 @@ static int eligible_child(pid_t pid, int options, struct task_struct *p) | |||
1140 | if (((p->exit_signal != SIGCHLD) ^ ((options & __WCLONE) != 0)) | 1140 | if (((p->exit_signal != SIGCHLD) ^ ((options & __WCLONE) != 0)) |
1141 | && !(options & __WALL)) | 1141 | && !(options & __WALL)) |
1142 | return 0; | 1142 | return 0; |
1143 | /* | ||
1144 | * Do not consider thread group leaders that are | ||
1145 | * in a non-empty thread group: | ||
1146 | */ | ||
1147 | if (delay_group_leader(p)) | ||
1148 | return 2; | ||
1149 | 1143 | ||
1150 | err = security_task_wait(p); | 1144 | err = security_task_wait(p); |
1151 | if (err) | 1145 | if (err) |
@@ -1497,10 +1491,9 @@ repeat: | |||
1497 | tsk = current; | 1491 | tsk = current; |
1498 | do { | 1492 | do { |
1499 | struct task_struct *p; | 1493 | struct task_struct *p; |
1500 | int ret; | ||
1501 | 1494 | ||
1502 | list_for_each_entry(p, &tsk->children, sibling) { | 1495 | list_for_each_entry(p, &tsk->children, sibling) { |
1503 | ret = eligible_child(pid, options, p); | 1496 | int ret = eligible_child(pid, options, p); |
1504 | if (!ret) | 1497 | if (!ret) |
1505 | continue; | 1498 | continue; |
1506 | 1499 | ||
@@ -1524,19 +1517,17 @@ repeat: | |||
1524 | retval = wait_task_stopped(p, | 1517 | retval = wait_task_stopped(p, |
1525 | (options & WNOWAIT), infop, | 1518 | (options & WNOWAIT), infop, |
1526 | stat_addr, ru); | 1519 | stat_addr, ru); |
1527 | } else if (p->exit_state == EXIT_ZOMBIE) { | 1520 | } else if (p->exit_state == EXIT_ZOMBIE && |
1521 | !delay_group_leader(p)) { | ||
1528 | /* | 1522 | /* |
1529 | * Eligible but we cannot release it yet: | 1523 | * We don't reap group leaders with subthreads. |
1530 | */ | 1524 | */ |
1531 | if (ret == 2) | ||
1532 | goto check_continued; | ||
1533 | if (!likely(options & WEXITED)) | 1525 | if (!likely(options & WEXITED)) |
1534 | continue; | 1526 | continue; |
1535 | retval = wait_task_zombie(p, | 1527 | retval = wait_task_zombie(p, |
1536 | (options & WNOWAIT), infop, | 1528 | (options & WNOWAIT), infop, |
1537 | stat_addr, ru); | 1529 | stat_addr, ru); |
1538 | } else if (p->exit_state != EXIT_DEAD) { | 1530 | } else if (p->exit_state != EXIT_DEAD) { |
1539 | check_continued: | ||
1540 | /* | 1531 | /* |
1541 | * It's running now, so it might later | 1532 | * It's running now, so it might later |
1542 | * exit, stop, or stop and then continue. | 1533 | * exit, stop, or stop and then continue. |