From: Mister B on
I have inherited some code (Red Hat Linux) for a multi-threaded
application. One thread uses sigaction() to set a signal-handler for
SIGALRM, calls alarm(), then does a write() to a blocking Unix Socket.

Before telling me how I could improve this (e.g. non-blocking sockets,
or using sigwatch() etc), can you answer the following question: Am I
guaranteed that this thread will receive the SIGALRM?
[Googling gives conflicting advice, e.g. "A caught, non-masked signal
that is caused by a particular thread will be handled by that thread
e.g. Alarm or timer signals requested by the thread", but "...If you
block SIGALRM in all threads but one, then that one thread will be the
one which receives the signal. If more than one threads has the signal
unblocked, it is unspecified which one will receive the signal."]

My actual problem is that the reader of the socket is not reading, and
after a while the write() blocks [presumably when the socket fills
up], and the alarm() interrupts it - fine. But, sometimes, exactly 30
seconds later, the process is killed by SIGALRM - I'm not sure which
thread or why? I wondering if a thread might be receiving a SIGALRM
unexpectedly.

Mark
From: Xavier Roche on
Mister B wrote:
> Before telling me how I could improve this (e.g. non-blocking sockets,
> or using sigwatch() etc), can you answer the following question: Am I
> guaranteed that this thread will receive the SIGALRM?

Nope.
<http://www.opengroup.org/onlinepubs/000095399/functions/alarm.html>

"There were two possible choices for alarm generation in multi-threaded
applications: generation for the calling thread or generation for the
process. The first option would not have been particularly useful since
the alarm state is maintained on a per-process basis and the alarm that
is established by the last invocation of alarm() is the only one that
would be active.

Furthermore, allowing generation of an asynchronous signal for a thread
would have introduced an exception to the overall signal model. This
requires a compelling reason in order to be justified."

You can reflect the signal to the corresponding thread, however, using
pthread_kill()
(<http://www.opengroup.org/onlinepubs/000095399/functions/pthread_kill.html>)

But you will have to maintain a state for the process, of course, to
know which thread is to receive the signal.
From: Ersek, Laszlo on
On Thu, 29 Jul 2010, Xavier Roche wrote:

> Mister B wrote:
>> Before telling me how I could improve this (e.g. non-blocking sockets,
>> or using sigwatch() etc), can you answer the following question: Am I
>> guaranteed that this thread will receive the SIGALRM?
>
> Nope.
> <http://www.opengroup.org/onlinepubs/000095399/functions/alarm.html>
>
> "There were two possible choices for alarm generation in multi-threaded
> applications: generation for the calling thread or generation for the
> process. The first option would not have been particularly useful since the
> alarm state is maintained on a per-process basis and the alarm that is
> established by the last invocation of alarm() is the only one that would be
> active.
>
> Furthermore, allowing generation of an asynchronous signal for a thread would
> have introduced an exception to the overall signal model. This requires a
> compelling reason in order to be justified."
>
> You can reflect the signal to the corresponding thread, however, using
> pthread_kill()
> (<http://www.opengroup.org/onlinepubs/000095399/functions/pthread_kill.html>)

Or block SIGALRM in all other threads.

lacos
From: Xavier Roche on
Ersek, Laszlo wrote:
> Or block SIGALRM in all other threads.

What for ? You would miss the signal in this case ?

If my understanding is correct, kill() selects a random thread on a
process for signal handling ; at least that's what pthreads(7) on Linux
says:

- POSIX.1 distinguishes the notions of signals that are directed to the
process as a whole and signals that are directed to individual threads.
According to POSIX.1, a process-directed signal (sent using kill(2),
for example) should be handled by a single, arbitrarily selected thread
within the process.
From: Rainer Weikusat on
Xavier Roche <xroche(a)free.fr.NOSPAM.invalid> writes:
> Ersek, Laszlo wrote:
>> Or block SIGALRM in all other threads.
>
> What for ? You would miss the signal in this case ?
>
> If my understanding is correct, kill() selects a random thread on a
> process for signal handling ; at least that's what pthreads(7) on
> Linux says:
>
> - POSIX.1 distinguishes the notions of signals that are directed to
> the process as a whole and signals that are directed to individual
> threads. According to POSIX.1, a process-directed signal (sent using
> kill(2), for example) should be handled by a single, arbitrarily
> selected thread within the process.

Signals generated for a process are supposed to be delivered to a
arbitrary, suitable thread, that is, one which is either blocked in a
sigwait call or has not blocked the signal, or to remain pending until
either a thread becomes 'suitable' (calls sigwait or unblocks the
signal) or the signal disposition is changed to 'ignore'.