diff options
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index b4a935c72159..84d13d6bb30b 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -1550,17 +1550,41 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, | |||
1550 | return 0; | 1550 | return 0; |
1551 | } | 1551 | } |
1552 | 1552 | ||
1553 | /* | 1553 | /* slay zombie? */ |
1554 | * We don't reap group leaders with subthreads. | 1554 | if (p->exit_state == EXIT_ZOMBIE) { |
1555 | */ | 1555 | /* we don't reap group leaders with subthreads */ |
1556 | if (p->exit_state == EXIT_ZOMBIE && !delay_group_leader(p)) | 1556 | if (!delay_group_leader(p)) |
1557 | return wait_task_zombie(wo, p); | 1557 | return wait_task_zombie(wo, p); |
1558 | 1558 | ||
1559 | /* | 1559 | /* |
1560 | * It's stopped or running now, so it might | 1560 | * Allow access to stopped/continued state via zombie by |
1561 | * later continue, exit, or stop again. | 1561 | * falling through. Clearing of notask_error is complex. |
1562 | */ | 1562 | * |
1563 | wo->notask_error = 0; | 1563 | * When !@ptrace: |
1564 | * | ||
1565 | * If WEXITED is set, notask_error should naturally be | ||
1566 | * cleared. If not, subset of WSTOPPED|WCONTINUED is set, | ||
1567 | * so, if there are live subthreads, there are events to | ||
1568 | * wait for. If all subthreads are dead, it's still safe | ||
1569 | * to clear - this function will be called again in finite | ||
1570 | * amount time once all the subthreads are released and | ||
1571 | * will then return without clearing. | ||
1572 | * | ||
1573 | * When @ptrace: | ||
1574 | * | ||
1575 | * Stopped state is per-task and thus can't change once the | ||
1576 | * target task dies. Only continued and exited can happen. | ||
1577 | * Clear notask_error if WCONTINUED | WEXITED. | ||
1578 | */ | ||
1579 | if (likely(!ptrace) || (wo->wo_flags & (WCONTINUED | WEXITED))) | ||
1580 | wo->notask_error = 0; | ||
1581 | } else { | ||
1582 | /* | ||
1583 | * @p is alive and it's gonna stop, continue or exit, so | ||
1584 | * there always is something to wait for. | ||
1585 | */ | ||
1586 | wo->notask_error = 0; | ||
1587 | } | ||
1564 | 1588 | ||
1565 | if (task_stopped_code(p, ptrace)) | 1589 | if (task_stopped_code(p, ptrace)) |
1566 | return wait_task_stopped(wo, ptrace, p); | 1590 | return wait_task_stopped(wo, ptrace, p); |