This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: pthread_sigaction() ?


Hi,

Xavier Roche wrote:

> int pthread_sigaction_np(int signum, const struct sigaction *act,
>                          struct sigaction *oldact);
[...]
> Any thoughts on this ? No use case maybe ? [my use case was the
> ability to locally handle signals to be able to siglongjmp() back to
> a defined state on a given code section, without modifying the
> global signal handler]

Could you elaborate on the use case?  When this thread receives the
signal, after doing something special does it call the old global
signal handler?  I guess what's puzzling to me is how to get
reasonable behavior without coordination with the rest of the process
even with the ability to set thread-specific signal handlers.

Example 1
---------
When the thread receives SIGUSR1, it will set a variable and when
control returns to the main loop, it will flush some output.  So
people can use this when impatient to urge your thread on a little.

If no other thread has its own use for SIGUSR1, you can set a global
handler and ask the author of calling code to use pthread_sigmask to
ensure SIGUSR1 only gets delivered to your thread.  Not a big problem.
On the other hand, if you are writing library code and do not control
what SIGUSR1 is used for in general, then there is a risk that someone
will use kill(2) to send SIGUSR1 to the process for some other purpose
and the signal is delivered to your thread, unintentionally triggering
the thread-specific behavior!  So one _has_ to coordinate in that
case.

A thread-specific handler would be useful in this example if (1) the
signal is not meant to ever be delivered to the process as a whole
with "kill" and (2) multiple threads want to be able to receive the
signal, for different thread-specific purposes.

Example 2
---------
Suppose your thread is not prepared to deal with interrupted system
calls, so you want to set the SA_RESTART flag to make sure the thread
never receives EINTR as an error.  Other threads can remain unaffected.
This is starting to sound like a more compelling use case to me ---
ideally you would want to start handling EINTR, but lacking that, the
best tools you have are to use pthread_sigmask to block problematic
signals from your thread or set the SA_RESTART flag for such signals.

Sadly, I do not think pthread_sigaction would help much --- it does
not stop other threads from adding signal handlers later, for example.

Example 3
---------
Your thread implements a state machine, using the program counter to
represent the current state, and sometimes uses blocking system calls
when in certain states.  You want to use signals to (1) interrupt any
such pending system call and (2) transition to some other specific
state.

Unfortunately as discussed under example 1, signal numbers are a
scarce resource that requires coordination.  I suppose I would suggest
using a global signal handler that reads a thread-local variable to
decide what to do.  That's how an implementation of pthread_sigaction
would work, presumably; letting applications take care of it means the
cost of an extra thread-local variable does not have to be paid by
applications that don't need it.

Hope that helps,
Jonathan


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]