diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/exit.c | 88 |
1 files changed, 39 insertions, 49 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 549c0558ba68..bfb1c0e940e8 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -249,7 +249,7 @@ static int has_stopped_jobs(struct pid *pgrp) | |||
249 | struct task_struct *p; | 249 | struct task_struct *p; |
250 | 250 | ||
251 | do_each_pid_task(pgrp, PIDTYPE_PGID, p) { | 251 | do_each_pid_task(pgrp, PIDTYPE_PGID, p) { |
252 | if (p->state != TASK_STOPPED) | 252 | if (!task_is_stopped(p)) |
253 | continue; | 253 | continue; |
254 | retval = 1; | 254 | retval = 1; |
255 | break; | 255 | break; |
@@ -614,7 +614,7 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced) | |||
614 | p->parent = p->real_parent; | 614 | p->parent = p->real_parent; |
615 | add_parent(p); | 615 | add_parent(p); |
616 | 616 | ||
617 | if (p->state == TASK_TRACED) { | 617 | if (task_is_traced(p)) { |
618 | /* | 618 | /* |
619 | * If it was at a trace stop, turn it into | 619 | * If it was at a trace stop, turn it into |
620 | * a normal stop since it's no longer being | 620 | * a normal stop since it's no longer being |
@@ -1563,60 +1563,51 @@ repeat: | |||
1563 | } | 1563 | } |
1564 | allowed = 1; | 1564 | allowed = 1; |
1565 | 1565 | ||
1566 | switch (p->state) { | 1566 | if (task_is_stopped_or_traced(p)) { |
1567 | case TASK_TRACED: | ||
1568 | /* | ||
1569 | * When we hit the race with PTRACE_ATTACH, | ||
1570 | * we will not report this child. But the | ||
1571 | * race means it has not yet been moved to | ||
1572 | * our ptrace_children list, so we need to | ||
1573 | * set the flag here to avoid a spurious ECHILD | ||
1574 | * when the race happens with the only child. | ||
1575 | */ | ||
1576 | flag = 1; | ||
1577 | if (!my_ptrace_child(p)) | ||
1578 | continue; | ||
1579 | /*FALLTHROUGH*/ | ||
1580 | case TASK_STOPPED: | ||
1581 | /* | 1567 | /* |
1582 | * It's stopped now, so it might later | 1568 | * It's stopped now, so it might later |
1583 | * continue, exit, or stop again. | 1569 | * continue, exit, or stop again. |
1570 | * | ||
1571 | * When we hit the race with PTRACE_ATTACH, we | ||
1572 | * will not report this child. But the race | ||
1573 | * means it has not yet been moved to our | ||
1574 | * ptrace_children list, so we need to set the | ||
1575 | * flag here to avoid a spurious ECHILD when | ||
1576 | * the race happens with the only child. | ||
1584 | */ | 1577 | */ |
1585 | flag = 1; | 1578 | flag = 1; |
1586 | if (!(options & WUNTRACED) && | 1579 | |
1587 | !my_ptrace_child(p)) | 1580 | if (!my_ptrace_child(p)) { |
1588 | continue; | 1581 | if (task_is_traced(p)) |
1582 | continue; | ||
1583 | if (!(options & WUNTRACED)) | ||
1584 | continue; | ||
1585 | } | ||
1586 | |||
1589 | retval = wait_task_stopped(p, ret == 2, | 1587 | retval = wait_task_stopped(p, ret == 2, |
1590 | (options & WNOWAIT), | 1588 | (options & WNOWAIT), infop, |
1591 | infop, | 1589 | stat_addr, ru); |
1592 | stat_addr, ru); | ||
1593 | if (retval == -EAGAIN) | 1590 | if (retval == -EAGAIN) |
1594 | goto repeat; | 1591 | goto repeat; |
1595 | if (retval != 0) /* He released the lock. */ | 1592 | if (retval != 0) /* He released the lock. */ |
1596 | goto end; | 1593 | goto end; |
1597 | break; | 1594 | } else if (p->exit_state == EXIT_DEAD) { |
1598 | default: | 1595 | continue; |
1599 | // case EXIT_DEAD: | 1596 | } else if (p->exit_state == EXIT_ZOMBIE) { |
1600 | if (p->exit_state == EXIT_DEAD) | 1597 | /* |
1598 | * Eligible but we cannot release it yet: | ||
1599 | */ | ||
1600 | if (ret == 2) | ||
1601 | goto check_continued; | ||
1602 | if (!likely(options & WEXITED)) | ||
1601 | continue; | 1603 | continue; |
1602 | // case EXIT_ZOMBIE: | 1604 | retval = wait_task_zombie(p, |
1603 | if (p->exit_state == EXIT_ZOMBIE) { | 1605 | (options & WNOWAIT), infop, |
1604 | /* | 1606 | stat_addr, ru); |
1605 | * Eligible but we cannot release | 1607 | /* He released the lock. */ |
1606 | * it yet: | 1608 | if (retval != 0) |
1607 | */ | 1609 | goto end; |
1608 | if (ret == 2) | 1610 | } else { |
1609 | goto check_continued; | ||
1610 | if (!likely(options & WEXITED)) | ||
1611 | continue; | ||
1612 | retval = wait_task_zombie( | ||
1613 | p, (options & WNOWAIT), | ||
1614 | infop, stat_addr, ru); | ||
1615 | /* He released the lock. */ | ||
1616 | if (retval != 0) | ||
1617 | goto end; | ||
1618 | break; | ||
1619 | } | ||
1620 | check_continued: | 1611 | check_continued: |
1621 | /* | 1612 | /* |
1622 | * It's running now, so it might later | 1613 | * It's running now, so it might later |
@@ -1625,12 +1616,11 @@ check_continued: | |||
1625 | flag = 1; | 1616 | flag = 1; |
1626 | if (!unlikely(options & WCONTINUED)) | 1617 | if (!unlikely(options & WCONTINUED)) |
1627 | continue; | 1618 | continue; |
1628 | retval = wait_task_continued( | 1619 | retval = wait_task_continued(p, |
1629 | p, (options & WNOWAIT), | 1620 | (options & WNOWAIT), infop, |
1630 | infop, stat_addr, ru); | 1621 | stat_addr, ru); |
1631 | if (retval != 0) /* He released the lock. */ | 1622 | if (retval != 0) /* He released the lock. */ |
1632 | goto end; | 1623 | goto end; |
1633 | break; | ||
1634 | } | 1624 | } |
1635 | } | 1625 | } |
1636 | if (!flag) { | 1626 | if (!flag) { |