diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 209eec11eef5..3d3adb94561d 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -1903,19 +1903,36 @@ relock: | |||
1903 | void exit_signals(struct task_struct *tsk) | 1903 | void exit_signals(struct task_struct *tsk) |
1904 | { | 1904 | { |
1905 | int group_stop = 0; | 1905 | int group_stop = 0; |
1906 | struct task_struct *t; | ||
1906 | 1907 | ||
1907 | spin_lock_irq(&tsk->sighand->siglock); | 1908 | if (thread_group_empty(tsk) || signal_group_exit(tsk->signal)) { |
1908 | if (unlikely(tsk->signal->group_stop_count) && | 1909 | tsk->flags |= PF_EXITING; |
1909 | !--tsk->signal->group_stop_count) { | 1910 | return; |
1910 | tsk->signal->flags = SIGNAL_STOP_STOPPED; | ||
1911 | group_stop = 1; | ||
1912 | } | 1911 | } |
1913 | 1912 | ||
1913 | spin_lock_irq(&tsk->sighand->siglock); | ||
1914 | /* | 1914 | /* |
1915 | * From now this task is not visible for group-wide signals, | 1915 | * From now this task is not visible for group-wide signals, |
1916 | * see wants_signal(), do_signal_stop(). | 1916 | * see wants_signal(), do_signal_stop(). |
1917 | */ | 1917 | */ |
1918 | tsk->flags |= PF_EXITING; | 1918 | tsk->flags |= PF_EXITING; |
1919 | if (!signal_pending(tsk)) | ||
1920 | goto out; | ||
1921 | |||
1922 | /* It could be that __group_complete_signal() choose us to | ||
1923 | * notify about group-wide signal. Another thread should be | ||
1924 | * woken now to take the signal since we will not. | ||
1925 | */ | ||
1926 | for (t = tsk; (t = next_thread(t)) != tsk; ) | ||
1927 | if (!signal_pending(t) && !(t->flags & PF_EXITING)) | ||
1928 | recalc_sigpending_and_wake(t); | ||
1929 | |||
1930 | if (unlikely(tsk->signal->group_stop_count) && | ||
1931 | !--tsk->signal->group_stop_count) { | ||
1932 | tsk->signal->flags = SIGNAL_STOP_STOPPED; | ||
1933 | group_stop = 1; | ||
1934 | } | ||
1935 | out: | ||
1919 | spin_unlock_irq(&tsk->sighand->siglock); | 1936 | spin_unlock_irq(&tsk->sighand->siglock); |
1920 | 1937 | ||
1921 | if (unlikely(group_stop)) { | 1938 | if (unlikely(group_stop)) { |