aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 3fca710a5cd7..209eec11eef5 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1739,7 +1739,7 @@ static int do_signal_stop(int signr)
1739 * stop is always done with the siglock held, 1739 * stop is always done with the siglock held,
1740 * so this check has no races. 1740 * so this check has no races.
1741 */ 1741 */
1742 if (!t->exit_state && 1742 if (!(t->flags & PF_EXITING) &&
1743 !task_is_stopped_or_traced(t)) { 1743 !task_is_stopped_or_traced(t)) {
1744 stop_count++; 1744 stop_count++;
1745 signal_wake_up(t, 0); 1745 signal_wake_up(t, 0);
@@ -1900,6 +1900,31 @@ relock:
1900 return signr; 1900 return signr;
1901} 1901}
1902 1902
1903void exit_signals(struct task_struct *tsk)
1904{
1905 int group_stop = 0;
1906
1907 spin_lock_irq(&tsk->sighand->siglock);
1908 if (unlikely(tsk->signal->group_stop_count) &&
1909 !--tsk->signal->group_stop_count) {
1910 tsk->signal->flags = SIGNAL_STOP_STOPPED;
1911 group_stop = 1;
1912 }
1913
1914 /*
1915 * From now this task is not visible for group-wide signals,
1916 * see wants_signal(), do_signal_stop().
1917 */
1918 tsk->flags |= PF_EXITING;
1919 spin_unlock_irq(&tsk->sighand->siglock);
1920
1921 if (unlikely(group_stop)) {
1922 read_lock(&tasklist_lock);
1923 do_notify_parent_cldstop(tsk, CLD_STOPPED);
1924 read_unlock(&tasklist_lock);
1925 }
1926}
1927
1903EXPORT_SYMBOL(recalc_sigpending); 1928EXPORT_SYMBOL(recalc_sigpending);
1904EXPORT_SYMBOL_GPL(dequeue_signal); 1929EXPORT_SYMBOL_GPL(dequeue_signal);
1905EXPORT_SYMBOL(flush_signals); 1930EXPORT_SYMBOL(flush_signals);