diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 364fc95bf97c..acdfc0549c6f 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -96,15 +96,27 @@ static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked) | |||
96 | 96 | ||
97 | #define PENDING(p,b) has_pending_signals(&(p)->signal, (b)) | 97 | #define PENDING(p,b) has_pending_signals(&(p)->signal, (b)) |
98 | 98 | ||
99 | fastcall void recalc_sigpending_tsk(struct task_struct *t) | 99 | static int recalc_sigpending_tsk(struct task_struct *t) |
100 | { | 100 | { |
101 | if (t->signal->group_stop_count > 0 || | 101 | if (t->signal->group_stop_count > 0 || |
102 | (freezing(t)) || | 102 | (freezing(t)) || |
103 | PENDING(&t->pending, &t->blocked) || | 103 | PENDING(&t->pending, &t->blocked) || |
104 | PENDING(&t->signal->shared_pending, &t->blocked)) | 104 | PENDING(&t->signal->shared_pending, &t->blocked)) { |
105 | set_tsk_thread_flag(t, TIF_SIGPENDING); | 105 | set_tsk_thread_flag(t, TIF_SIGPENDING); |
106 | else | 106 | return 1; |
107 | clear_tsk_thread_flag(t, TIF_SIGPENDING); | 107 | } |
108 | clear_tsk_thread_flag(t, TIF_SIGPENDING); | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | /* | ||
113 | * After recalculating TIF_SIGPENDING, we need to make sure the task wakes up. | ||
114 | * This is superfluous when called on current, the wakeup is a harmless no-op. | ||
115 | */ | ||
116 | void recalc_sigpending_and_wake(struct task_struct *t) | ||
117 | { | ||
118 | if (recalc_sigpending_tsk(t)) | ||
119 | signal_wake_up(t, 0); | ||
108 | } | 120 | } |
109 | 121 | ||
110 | void recalc_sigpending(void) | 122 | void recalc_sigpending(void) |
@@ -744,7 +756,7 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t) | |||
744 | action->sa.sa_handler = SIG_DFL; | 756 | action->sa.sa_handler = SIG_DFL; |
745 | if (blocked) { | 757 | if (blocked) { |
746 | sigdelset(&t->blocked, sig); | 758 | sigdelset(&t->blocked, sig); |
747 | recalc_sigpending_tsk(t); | 759 | recalc_sigpending_and_wake(t); |
748 | } | 760 | } |
749 | } | 761 | } |
750 | ret = specific_send_sig_info(sig, info, t); | 762 | ret = specific_send_sig_info(sig, info, t); |
@@ -2273,7 +2285,7 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) | |||
2273 | rm_from_queue_full(&mask, &t->signal->shared_pending); | 2285 | rm_from_queue_full(&mask, &t->signal->shared_pending); |
2274 | do { | 2286 | do { |
2275 | rm_from_queue_full(&mask, &t->pending); | 2287 | rm_from_queue_full(&mask, &t->pending); |
2276 | recalc_sigpending_tsk(t); | 2288 | recalc_sigpending_and_wake(t); |
2277 | t = next_thread(t); | 2289 | t = next_thread(t); |
2278 | } while (t != current); | 2290 | } while (t != current); |
2279 | } | 2291 | } |