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.

Reply via email to