On Mon, Jul 09, 2018 at 10:59:54PM +0200, Alexander Bluhm wrote:
> 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@.

While I think this is a step in the right direction I don't think is the
proper solution to the problem.

I don't think this handles pthread_kill() signals and I agree with mpi@
that the path should be split between thread signals and process signals.

I am tracking this issue myself for almost two weeks now and while
indeed this diff seems to workaround the posixsuite issue, it does still
manifest in complex scenarios like lang/mono.

I will try to come up with something better in the following days.
In the meantime if you guys want to commit this bit, I will not
object.

> 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