On Mon, Jul 09, 2018 at 11:27:55AM -0900, Philip Guenther wrote: > Those signals are handled by the first thread that > > doesn't have them masked. In that case, it should be put on the pending > > list of the process and any unmasking operation should check the pending > > list on whether a signal should be delivered delayed. > > > > Yep.
This is my original diff with some twaeks from visa@. bluhm Index: kern/kern_sig.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/kern/kern_sig.c,v retrieving revision 1.220 diff -u -p -r1.220 kern_sig.c --- kern/kern_sig.c 28 Apr 2018 03:13:04 -0000 1.220 +++ kern/kern_sig.c 9 Jul 2018 20:36:07 -0000 @@ -1155,14 +1155,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 @@ -1840,7 +1843,7 @@ userret(struct proc *p) KERNEL_UNLOCK(); } - if (SIGPENDING(p)) { + if (SIGPENDING(p) != 0) { KERNEL_LOCK(); while ((signum = CURSIG(p)) != 0) postsig(p, signum); Index: sys/signalvar.h =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/sys/signalvar.h,v retrieving revision 1.30 diff -u -p -r1.30 signalvar.h --- sys/signalvar.h 24 Mar 2018 04:13:59 -0000 1.30 +++ sys/signalvar.h 9 Jul 2018 20:52:50 -0000 @@ -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.