On 29/06/18(Fri) 16:21, Alexander Bluhm wrote:
> On Thu, Jun 28, 2018 at 01:54:29PM +0200, Martin Pieuchot wrote:
> > > It may happen that the worker thread is in the signal handler and
> > > also blocks the signals.
> >
> > Are you saying that the worker thread modified its mask itself, via
> > a syscall, or that the kernel changed `p_sigmask'?
> 
> Unless SA_NODEFER is set, the kernel masks signals while the handler
> is running.  This is done here:
> 
>         if ((sa->sa_flags & SA_NODEFER) == 0)
>                 sa->sa_mask |= sigmask(signum);
>         ps->ps_catchmask[signum] = sa->sa_mask &~ sigcantmask;
> ...
>         atomic_setbits_int(&p->p_sigmask, ps->ps_catchmask[signum]);
> 
> > >                           Then all threads block them and ptsignal()
> > > sends it to the main thread.  In the test program the main thread
> > > blocks them forever and the process gets stuck.
> > 
> > Can you point us to the piece of code containing this logic?  Is it:
> >     
> >     * [...].  Otherwise, mark it pending on the
> >     * main thread.
> 
> Yes.  All threads mask the signal so it ends pending at the main
> thread.  prsignal() calls ptsignal(ps_mainproc), so this thread is
> used if the TAILQ_FOREACH(q, &pr->ps_threads, p_thr_link) loop finds
> no match.
> 
> > > According to POSIX any thread should process the signal when it
> > > unblocks.
> > 
> > Does that mean we should rather mark the signal pending on the thread
> > will unblock it?  Do we have a way to know that it will unblock it (see
> > my first question)?
> 
> The problem is that POSIX has signals that are sent to processes
> and signals sent to individual threads.  Our kernel does not support
> this properly.
> 
> We can improve the heuristic.  But still we don't know that the
> thread in the signal handler will unblock the signal first.  It is
> the case for the programs in posixtestsuite, so your suggestion
> could work.

You mentioned NetBSD in your previous email, did you look at how they
solve this problem?

>              But I think it is less general than my solution.  Also
> I don't know how to figure out whether a thread is currently
> processing a signal handler.  And still this does not mean it will
> finish and unblock.

Here's an idea:

  We need another field to save which signals are masked because the
thread is currently executing a handler.  Then when a signal is masked,
before looking for a sibling to deliver it, we check if it is masked
because of a signal handler.  If that's the case we know it can be
delivered soon.

> My solution has the drawback that signals sent to the main thread
> may be handled like signals sent to the process.

I'm afraid that your solution goes in the wrong direction.  I think
we have to improve the heuristic.  We have to untangle per-thread and
per-process bits.

Reply via email to