Subject: Re: better signal delivery to threads
To: None <M.Drochner@fz-juelich.de>
From: Nathan J. Williams <nathanw@wasabisystems.com>
List: tech-userlevel
Date: 08/22/2005 17:17:42
Matthias Drochner <M.Drochner@fz-juelich.de> writes:

> Signals are delivered to the wrong thread.
> There are 2 threads in the Python interpreter (one
> the main thread of the test script, the other appearently a
> leftover of another script executed previously, or perhaps
> related to logging) which don't block the signal in question,
> and it happens reproducibly that the other one gets the signal
> while the intended target is left in sigsuspend().
> 
> (This might be technically not the fault of NetBSD's libpthread.
> Using threads and signals to processes together is just a bad idea.
> But in cases like script interpreters, or unsuspecting libraries
> pulled in by threaded programs, we have to live with a mix
> of these worlds.)

As currently specified, the implementation is permitted to pick any
thread where the signal is unblocked or that is calling sigwait() for
the relevant signal.

> We might be more clever to select the thread to deliver a signal
> to. Currently, libpthread takes a randon thread not blocking the
> signal, just preferring threads which are not blocked in a system
> call (as I understand the code). The appended patch modifies this
> to prefer threads which are in sigsuspend(). This makes the Python
> selftest succeed. (just a proof-of-idea, probably not exact enough)

I don't completely object, but it seems to be purely for the benefit
of one program, which is relying on unspecified behavior.

> Thinking about this, would there be anything wrong with waking
> up multiple threads?
> Only one of all threads waiting in sig*wait*() because it is
> specified so, but otherwise all blocked threads (modulo sigmask)
> could be awoken.
> There is a difference between "delivering a signal" and "awake
> a thread" of course -- a signal handler is to be called only once.

I think this is okay but it is definitely a grey area, and outside of
the intended use of sigsuspend() - the standard model for using
sigsuspend() assumes that all other threads have the signal blocked.


> At that point it should be made sure probably that the threads
> are not awoken before the signal handler is finished, to avoid
> deadlock situations.
> But what happens if a signal handler is left per longjmp()?

I would say that that doesn't qualify as "returning" from the signal
handler and doesn't need to be considered.

        - Nathan