Messages in this thread Patch in this message | | | Date | Sun, 29 Sep 2002 12:27:11 +0200 (CEST) | From | Ingo Molnar <> | Subject | Re: 2.5.39: Signal delivery to thread groups: Bug or feature |
| |
On Sat, 28 Sep 2002, Axel wrote:
> The main signal dispatching function send_sig_info in kernel/signal.c > requires at the moment an installed signal handler for delivery of > signals to members of the thread group.
i fixed this bug, see the attached attached patch, it's against BK-curr.
It fixes the testcase Ulrich created from your description - does it fix your testcase as well? (Ulrich added this testcase to NPTL, should show up in the next drop.)
we still have one more problem left in the signal handling area: atomicity of signal delivery. Eg. right now it's possible to have a signal 'in flight' for one specific thread, which manages to block it before handling the signal. What should the behavior be in that case? Does POSIX say anything about this?
Ingo
--- linux/kernel/signal.c.orig Sun Sep 29 11:59:03 2002 +++ linux/kernel/signal.c Sun Sep 29 12:17:14 2002 @@ -874,9 +874,23 @@ return err; } +struct task_struct * find_unblocked_thread(struct task_struct *p, int signr) +{ + struct task_struct *tmp; + struct list_head *l; + struct pid *pid; + + for_each_task_pid(p->tgid, PIDTYPE_TGID, tmp, l, pid) + if (!sigismember(&tmp->blocked, signr) && + !sigismember(&tmp->real_blocked, signr)) + return tmp; + return NULL; +} + int send_sig_info(int sig, struct siginfo *info, struct task_struct *p) { + struct task_struct *t; unsigned long flags; int ret = 0; @@ -905,21 +919,19 @@ if (sig_ignored(p, sig)) goto out_unlock; - /* blocked (or ptraced) signals get posted */ - spin_lock(&p->sigmask_lock); - if ((p->ptrace & PT_PTRACED) || sigismember(&p->blocked, sig) || - sigismember(&p->real_blocked, sig)) { - spin_unlock(&p->sigmask_lock); + if (sig_kernel_specific(sig)) goto out_send; - } - spin_unlock(&p->sigmask_lock); + /* Does any of the threads unblock the signal? */ + t = find_unblocked_thread(p, sig); + if (!t) { + ret = __send_sig_info(sig, info, p, 1); + goto out_unlock; + } if (sig_kernel_broadcast(sig) || sig_kernel_coredump(sig)) { ret = __broadcast_thread_group(p, sig); goto out_unlock; } - if (sig_kernel_specific(sig)) - goto out_send; /* must not happen */ BUG(); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |