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.
