This is the mail archive of the
mailing list for the libstdc++ project.
Re: signal and STL constructors conflict causing deadlock, or - __USE _MALLOC and RedHat 8.0
- From: Carlo Wood <carlo at alinoe dot com>
- To: "Honigstein, Bat-sheva" <bat-sheva dot honigstein at intel dot com>
- Cc: libstdc++ at gcc dot gnu dot org
- Date: Thu, 13 Mar 2003 14:33:19 +0100
- Subject: Re: signal and STL constructors conflict causing deadlock, or - __USE _MALLOC and RedHat 8.0
- References: <5243FD63F373284AB4F040F1D57116CD9978F9@hasmsx402.iil.intel.com>
On Thu, Mar 13, 2003 at 02:07:31PM +0200, Honigstein, Bat-sheva wrote:
> > I'm trying to create a timer, using signal (SIGALARM). In that timer
> a string is allocated. At the same time the main flow is also allocating
> strings. (This, of course, is a small example of a much more complex issue).
> When I compile my file with g++ sigmalloc.cpp -lpthread, I get a deadlock
> caused by the fact that the main flow was interrupted by the signal while in
> the string constructor.
Signals are often described as software interrupts. The kernel of a
multitasking Operating System such as UNIX switches between running
applications when either a running application goes to sleep (calls
a blocking system call or enters select(2) or poll(2)) or after a
certain period of time (ie. 10 ms). Signals are handled by the kernel
at the moment it switches between running processes, hence the word
software interrupts. Interrupting an application that doesn't go to
sleep within 10 ms is performed by a hardware interrupt though and
the program execution can be at any arbitrary point. When such an
application has pending signals, then the signal handler function is
called while the application is in a totally undefined state. For
instance, the application could be in the middle of a call to malloc(3)
or free(3), which makes it dangerous to allocate memory from within
a signal handler.
The result of how signals work is that signal handlers can only be
allowed to set a flag of a very simple type: sig_atomic_t (often an int).
This fact gives signals their real meaning: Signals are a way of
communication between processes or between the kernel and a process.
Signals fall in the category of IPC (Inter Process Communication),
just like pipes and UNIX sockets. For a correct understanding of
signals one has to see them as messages, not as interrupts.
Conclusion: you cannot implement a timer by executing code from the
signal handler. Instead, you should only toggle a flag, and catch
that flag in the mainloop of your application.
Most notably, during a SIGALARM - ANY lock can be set, and you should
not call ANY code that is trying to set any lock therefore, because
of the risk of a deadlock. You also should not call anything that might
try to allocate memory. Actually, you shouldn't even read/write global
state information (data that is also used by the application directly)
unless that read/write is atomic.
Carlo Wood <carlo at alinoe dot com>