diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-10-03 22:06:19 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-03 22:06:19 -0400 |
commit | 3c8c7b2f32c52b259daa7564fefd582146799b23 (patch) | |
tree | 59ff1ad0d6b7821d474d8fccafd884703684b6d7 /kernel/signal.c | |
parent | 7cb3cd090c2725b80561958a362c2ba15a7a8c86 (diff) | |
parent | 9123e0d78990246304fe681167b8d8097f1e02d7 (diff) |
Merge branch 'upstream-fixes'
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 34 |
1 files changed, 16 insertions, 18 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index b92c3c9f8b9a..619b027e92b5 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -936,34 +936,31 @@ force_sig_specific(int sig, struct task_struct *t) | |||
936 | * as soon as they're available, so putting the signal on the shared queue | 936 | * as soon as they're available, so putting the signal on the shared queue |
937 | * will be equivalent to sending it to one such thread. | 937 | * will be equivalent to sending it to one such thread. |
938 | */ | 938 | */ |
939 | #define wants_signal(sig, p, mask) \ | 939 | static inline int wants_signal(int sig, struct task_struct *p) |
940 | (!sigismember(&(p)->blocked, sig) \ | 940 | { |
941 | && !((p)->state & mask) \ | 941 | if (sigismember(&p->blocked, sig)) |
942 | && !((p)->flags & PF_EXITING) \ | 942 | return 0; |
943 | && (task_curr(p) || !signal_pending(p))) | 943 | if (p->flags & PF_EXITING) |
944 | 944 | return 0; | |
945 | if (sig == SIGKILL) | ||
946 | return 1; | ||
947 | if (p->state & (TASK_STOPPED | TASK_TRACED)) | ||
948 | return 0; | ||
949 | return task_curr(p) || !signal_pending(p); | ||
950 | } | ||
945 | 951 | ||
946 | static void | 952 | static void |
947 | __group_complete_signal(int sig, struct task_struct *p) | 953 | __group_complete_signal(int sig, struct task_struct *p) |
948 | { | 954 | { |
949 | unsigned int mask; | ||
950 | struct task_struct *t; | 955 | struct task_struct *t; |
951 | 956 | ||
952 | /* | 957 | /* |
953 | * Don't bother traced and stopped tasks (but | ||
954 | * SIGKILL will punch through that). | ||
955 | */ | ||
956 | mask = TASK_STOPPED | TASK_TRACED; | ||
957 | if (sig == SIGKILL) | ||
958 | mask = 0; | ||
959 | |||
960 | /* | ||
961 | * Now find a thread we can wake up to take the signal off the queue. | 958 | * Now find a thread we can wake up to take the signal off the queue. |
962 | * | 959 | * |
963 | * If the main thread wants the signal, it gets first crack. | 960 | * If the main thread wants the signal, it gets first crack. |
964 | * Probably the least surprising to the average bear. | 961 | * Probably the least surprising to the average bear. |
965 | */ | 962 | */ |
966 | if (wants_signal(sig, p, mask)) | 963 | if (wants_signal(sig, p)) |
967 | t = p; | 964 | t = p; |
968 | else if (thread_group_empty(p)) | 965 | else if (thread_group_empty(p)) |
969 | /* | 966 | /* |
@@ -981,7 +978,7 @@ __group_complete_signal(int sig, struct task_struct *p) | |||
981 | t = p->signal->curr_target = p; | 978 | t = p->signal->curr_target = p; |
982 | BUG_ON(t->tgid != p->tgid); | 979 | BUG_ON(t->tgid != p->tgid); |
983 | 980 | ||
984 | while (!wants_signal(sig, t, mask)) { | 981 | while (!wants_signal(sig, t)) { |
985 | t = next_thread(t); | 982 | t = next_thread(t); |
986 | if (t == p->signal->curr_target) | 983 | if (t == p->signal->curr_target) |
987 | /* | 984 | /* |
@@ -1766,7 +1763,8 @@ do_signal_stop(int signr) | |||
1766 | * stop is always done with the siglock held, | 1763 | * stop is always done with the siglock held, |
1767 | * so this check has no races. | 1764 | * so this check has no races. |
1768 | */ | 1765 | */ |
1769 | if (t->state < TASK_STOPPED) { | 1766 | if (!t->exit_state && |
1767 | !(t->state & (TASK_STOPPED|TASK_TRACED))) { | ||
1770 | stop_count++; | 1768 | stop_count++; |
1771 | signal_wake_up(t, 0); | 1769 | signal_wake_up(t, 0); |
1772 | } | 1770 | } |