signals: kill rm_from_queue(), change prepare_signal() to use for_each_thread()
rm_from_queue() doesn't make sense. The only caller, prepare_signal(), can use rm_from_queue_full() with the same effect. While at it, change prepare_signal() to use for_each_thread() instead of do/while_each_thread. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Al Viro <viro@ZenIV.linux.org.uk> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Ingo Molnar <mingo@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Richard Weinberger <richard@nod.at> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Tejun Heo <tj@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
6114041aa7
Коммит
9490592f27
|
@ -728,29 +728,6 @@ static int rm_from_queue_full(sigset_t *mask, struct sigpending *s)
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* Remove signals in mask from the pending set and queue.
|
||||
* Returns 1 if any signals were found.
|
||||
*
|
||||
* All callers must be holding the siglock.
|
||||
*/
|
||||
static int rm_from_queue(unsigned long mask, struct sigpending *s)
|
||||
{
|
||||
struct sigqueue *q, *n;
|
||||
|
||||
if (!sigtestsetmask(&s->signal, mask))
|
||||
return 0;
|
||||
|
||||
sigdelsetmask(&s->signal, mask);
|
||||
list_for_each_entry_safe(q, n, &s->list, list) {
|
||||
if (q->info.si_signo < SIGRTMIN &&
|
||||
(mask & sigmask(q->info.si_signo))) {
|
||||
list_del_init(&q->list);
|
||||
__sigqueue_free(q);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int is_si_special(const struct siginfo *info)
|
||||
{
|
||||
|
@ -862,6 +839,7 @@ static bool prepare_signal(int sig, struct task_struct *p, bool force)
|
|||
{
|
||||
struct signal_struct *signal = p->signal;
|
||||
struct task_struct *t;
|
||||
sigset_t flush;
|
||||
|
||||
if (signal->flags & (SIGNAL_GROUP_EXIT | SIGNAL_GROUP_COREDUMP)) {
|
||||
if (signal->flags & SIGNAL_GROUP_COREDUMP)
|
||||
|
@ -873,26 +851,25 @@ static bool prepare_signal(int sig, struct task_struct *p, bool force)
|
|||
/*
|
||||
* This is a stop signal. Remove SIGCONT from all queues.
|
||||
*/
|
||||
rm_from_queue(sigmask(SIGCONT), &signal->shared_pending);
|
||||
t = p;
|
||||
do {
|
||||
rm_from_queue(sigmask(SIGCONT), &t->pending);
|
||||
} while_each_thread(p, t);
|
||||
siginitset(&flush, sigmask(SIGCONT));
|
||||
rm_from_queue_full(&flush, &signal->shared_pending);
|
||||
for_each_thread(p, t)
|
||||
rm_from_queue_full(&flush, &t->pending);
|
||||
} else if (sig == SIGCONT) {
|
||||
unsigned int why;
|
||||
/*
|
||||
* Remove all stop signals from all queues, wake all threads.
|
||||
*/
|
||||
rm_from_queue(SIG_KERNEL_STOP_MASK, &signal->shared_pending);
|
||||
t = p;
|
||||
do {
|
||||
siginitset(&flush, SIG_KERNEL_STOP_MASK);
|
||||
rm_from_queue_full(&flush, &signal->shared_pending);
|
||||
for_each_thread(p, t) {
|
||||
rm_from_queue_full(&flush, &t->pending);
|
||||
task_clear_jobctl_pending(t, JOBCTL_STOP_PENDING);
|
||||
rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending);
|
||||
if (likely(!(t->ptrace & PT_SEIZED)))
|
||||
wake_up_state(t, __TASK_STOPPED);
|
||||
else
|
||||
ptrace_trap_notify(t);
|
||||
} while_each_thread(p, t);
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify the parent with CLD_CONTINUED if we were stopped.
|
||||
|
|
Загрузка…
Ссылка в новой задаче