aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index c15e9792b088..5341e2141904 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2198,10 +2198,25 @@ relock:
2198 return signr; 2198 return signr;
2199} 2199}
2200 2200
2201/*
2202 * It could be that complete_signal() picked us to notify about the
2203 * group-wide signal. Another thread should be notified now to take
2204 * the signal since we will not.
2205 */
2206static void retarget_shared_pending(struct task_struct *tsk)
2207{
2208 struct task_struct *t;
2209
2210 t = tsk;
2211 while_each_thread(tsk, t) {
2212 if (!signal_pending(t) && !(t->flags & PF_EXITING))
2213 recalc_sigpending_and_wake(t);
2214 }
2215}
2216
2201void exit_signals(struct task_struct *tsk) 2217void exit_signals(struct task_struct *tsk)
2202{ 2218{
2203 int group_stop = 0; 2219 int group_stop = 0;
2204 struct task_struct *t;
2205 2220
2206 if (thread_group_empty(tsk) || signal_group_exit(tsk->signal)) { 2221 if (thread_group_empty(tsk) || signal_group_exit(tsk->signal)) {
2207 tsk->flags |= PF_EXITING; 2222 tsk->flags |= PF_EXITING;
@@ -2217,14 +2232,7 @@ void exit_signals(struct task_struct *tsk)
2217 if (!signal_pending(tsk)) 2232 if (!signal_pending(tsk))
2218 goto out; 2233 goto out;
2219 2234
2220 /* 2235 retarget_shared_pending(tsk);
2221 * It could be that __group_complete_signal() choose us to
2222 * notify about group-wide signal. Another thread should be
2223 * woken now to take the signal since we will not.
2224 */
2225 for (t = tsk; (t = next_thread(t)) != tsk; )
2226 if (!signal_pending(t) && !(t->flags & PF_EXITING))
2227 recalc_sigpending_and_wake(t);
2228 2236
2229 if (unlikely(tsk->group_stop & GROUP_STOP_PENDING) && 2237 if (unlikely(tsk->group_stop & GROUP_STOP_PENDING) &&
2230 task_participate_group_stop(tsk)) 2238 task_participate_group_stop(tsk))