Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 95135
b: refs/heads/master
c: 7e695a5
h: refs/heads/master
i:
  95133: f749c6e
  95131: c42e7e9
  95127: e0ce107
  95119: d1bd367
  95103: 160846e
v: v3
  • Loading branch information
Oleg Nesterov authored and Linus Torvalds committed Apr 30, 2008
1 parent 9498a0c commit 3c51f92
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2dce81bff28dceb2153c901883a56f278d91db65
refs/heads/master: 7e695a5ef5c1c768d7feb75cc61e42f13d763623
32 changes: 17 additions & 15 deletions trunk/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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);
}

/*
Expand Down Expand Up @@ -753,15 +756,16 @@ 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;
/*
* Short-circuit ignored signals and support queuing
* 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;

/*
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 3c51f92

Please sign in to comment.