This is the mail archive of the
mailing list for the glibc project.
Re: [libc-alpha] mt-application hanging in exit()
- From: Kaz Kylheku <kaz at ashi dot footprints dot net>
- To: Bertold Kolics <Bertold dot Kolics at Sun dot COM>
- Cc: Andreas Jaeger <aj at suse dot de>, <libc-alpha at sources dot redhat dot com>
- Date: Sat, 19 Jan 2002 12:10:39 -0800 (PST)
- Subject: Re: [libc-alpha] mt-application hanging in exit()
On Sat, 19 Jan 2002, Bertold Kolics wrote:
> I may have found the problem, but I still believe that there is a problem in glibc.
Nope, false alarm! Phew!
> Before setting up the signal handlers, I used to clear the signal mask of the process.
You should be aware that sigprocmask is restricted to use in a
single-threaded process. From Draft 7 POSIX, (June 14, 2001):
The use of the sigprocmask() function is unspecified
in a multi-threaded process.
Everyone who cares about writing code that can be compiled and linked
with a MT application should use pthread_sigmask. It will do the
same job as sigprocmask in a single-threaded process.
In GNU/Linux, the pthread_sigprocmask function takes care that the
application does not inadvertantly mess with some signals internal to
the threading library. But if you use sigprocmask, you can stomp all
> If this is the case, the application hangs. Otherwise, everything is OK.
> Then, I took a look at which signal is set before clearing the mask (sigismember())
> and found that SIGRTMIN is set.
> I understand the SIGRTMIN is the restart signal. What I don't understand is that
> why it affects the termination of the program if I clear the mask before creating
> any thread.
Because in order to use a signal reliably as an inter-thread
synchronization mechanism, you need to be able to block that signal until
the point when you are ready to catch it. If you unblock a signal that
doesn't belong to you, watch out.
The idea in __pthread_wait_for_restart_signal() is to atomically
unblock the restart signal, wait until it happens, and then reblock it.
That atomicity is provided by the sigsuspend() function, which is
a system call to the kernel.
If you unblock that signal prematurely, like for instance by calling
sigprocmask() in the application to clear it, you bring about that very
race condition which you hypothesized about in the earlier e-mail.
This really should be better documented. By the same token, people should
read POSIX more. :)