From 3c51f926516f3e4d2930c9d7c67390f802d05a61 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 30 Apr 2008 00:52:59 -0700 Subject: [PATCH] --- yaml --- r: 95135 b: refs/heads/master c: 7e695a5ef5c1c768d7feb75cc61e42f13d763623 h: refs/heads/master i: 95133: f749c6eabb9e03cb422c1911b050deb11f998133 95131: c42e7e933b7e3fb85ca79fe430d5ccd0ee7e7e7f 95127: e0ce10721d69e99df71b833dbb28fae9ef27923c 95119: d1bd3671793718648e2fb042e72ede8507377e76 95103: 160846eac1f86c9cdc2c362b7112cb7fd26f7aab v: v3 --- [refs] | 2 +- trunk/kernel/signal.c | 32 +++++++++++++++++--------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/[refs] b/[refs] index 1115f437901c..52fadc9b76aa 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2dce81bff28dceb2153c901883a56f278d91db65 +refs/heads/master: 7e695a5ef5c1c768d7feb75cc61e42f13d763623 diff --git a/trunk/kernel/signal.c b/trunk/kernel/signal.c index 0db1d93c4d68..359c4de7c772 100644 --- a/trunk/kernel/signal.c +++ b/trunk/kernel/signal.c @@ -558,24 +558,25 @@ static int check_kill_permission(int sig, struct siginfo *info, static void do_notify_parent_cldstop(struct task_struct *tsk, int why); /* - * Handle magic process-wide effects of stop/continue signals. - * Unlike the signal actions, these happen immediately at signal-generation + * Handle magic process-wide effects of stop/continue signals. Unlike + * the signal actions, these happen immediately at signal-generation * time regardless of blocking, ignoring, or handling. This does the * actual continuing for SIGCONT, but not the actual stopping for stop - * signals. The process stop is done as a signal action for SIG_DFL. + * signals. The process stop is done as a signal action for SIG_DFL. + * + * Returns true if the signal should be actually delivered, otherwise + * it should be dropped. */ -static void handle_stop_signal(int sig, struct task_struct *p) +static int prepare_signal(int sig, struct task_struct *p) { struct signal_struct *signal = p->signal; struct task_struct *t; - if (signal->flags & SIGNAL_GROUP_EXIT) + if (unlikely(signal->flags & SIGNAL_GROUP_EXIT)) { /* - * The process is in the middle of dying already. + * The process is in the middle of dying, nothing to do. */ - return; - - if (sig_kernel_stop(sig)) { + } else if (sig_kernel_stop(sig)) { /* * This is a stop signal. Remove SIGCONT from all queues. */ @@ -644,6 +645,8 @@ static void handle_stop_signal(int sig, struct task_struct *p) signal->flags &= ~SIGNAL_STOP_DEQUEUED; } } + + return !sig_ignored(p, sig); } /* @@ -753,7 +756,8 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, struct sigqueue *q; assert_spin_locked(&t->sighand->siglock); - handle_stop_signal(sig, t); + if (!prepare_signal(sig, t)) + return 0; pending = group ? &t->signal->shared_pending : &t->pending; /* @@ -761,7 +765,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, * exactly one non-rt signal, so that we can get more * detailed information about the cause of the signal. */ - if (sig_ignored(t, sig) || legacy_queue(pending, sig)) + if (legacy_queue(pending, sig)) return 0; /* @@ -1247,10 +1251,8 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group) if (!likely(lock_task_sighand(t, &flags))) goto ret; - handle_stop_signal(sig, t); - - ret = 1; - if (sig_ignored(t, sig)) + ret = 1; /* the signal is ignored */ + if (!prepare_signal(sig, t)) goto out; ret = 0;