From: bluhm Date: Wed, 11 Jul 2018 19:28:16 +0000 (+0000) Subject: If no thread can immediately handle a signal, which has been sent X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=3f0b58624f77a2c3f50097dc3510d689f9c832ff;p=openbsd If no thread can immediately handle a signal, which has been sent to the process, it is made pending at the main thread. There it could hang forever. So also check the main thread for signal delivery. This workaround fixes hung tests in posixtestsuite. The proper solution would be to split pending signals for process and threads. input visa@; OK guenther@ --- diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 823ab102b7b..7a8a7a9ac69 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.221 2018/07/10 04:19:59 guenther Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.222 2018/07/11 19:28:16 bluhm Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -1153,14 +1153,17 @@ issignal(struct proc *p) int s; for (;;) { - mask = p->p_siglist & ~p->p_sigmask; + mask = SIGPENDING(p); if (pr->ps_flags & PS_PPWAIT) mask &= ~stopsigmask; if (mask == 0) /* no signal to send */ return (0); signum = ffs((long)mask); mask = sigmask(signum); - atomic_clearbits_int(&p->p_siglist, mask); + if (p->p_siglist & mask) + atomic_clearbits_int(&p->p_siglist, mask); + else + atomic_clearbits_int(&pr->ps_mainproc->p_siglist, mask); /* * We should see pending but ignored signals @@ -1836,7 +1839,7 @@ userret(struct proc *p) KERNEL_UNLOCK(); } - if (SIGPENDING(p)) { + if (SIGPENDING(p) != 0) { KERNEL_LOCK(); while ((signum = CURSIG(p)) != 0) postsig(p, signum); diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index dd36d730e65..f5e0a07cb88 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: signalvar.h,v 1.31 2018/07/10 04:19:59 guenther Exp $ */ +/* $OpenBSD: signalvar.h,v 1.32 2018/07/11 19:28:16 bluhm Exp $ */ /* $NetBSD: signalvar.h,v 1.17 1996/04/22 01:23:31 christos Exp $ */ /* @@ -68,7 +68,9 @@ struct sigacts { /* * Check if process p has an unmasked signal pending. */ -#define SIGPENDING(p) (((p)->p_siglist & ~(p)->p_sigmask) != 0) +#define SIGPENDING(p) \ + (((p)->p_siglist | (p)->p_p->ps_mainproc->p_siglist) & \ + ~(p)->p_sigmask) /* * Determine signal that should be delivered to process p, the current @@ -76,10 +78,9 @@ struct sigacts { * action, the process stops in issignal(). */ #define CURSIG(p) \ - (((p)->p_siglist == 0 || \ - (((p)->p_p->ps_flags & PS_TRACED) == 0 && \ - ((p)->p_siglist & ~(p)->p_sigmask) == 0)) ? \ - 0 : issignal(p)) + (((((p)->p_siglist | (p)->p_p->ps_mainproc->p_siglist) == 0) || \ + (((p)->p_p->ps_flags & PS_TRACED) == 0 && SIGPENDING(p) == 0)) \ + ? 0 : issignal(p)) /* * Clear a pending signal from a process.