Home > Archive > Unix Programming > September 2005 > signal handling
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
|
|
| Massimo Cafaro 2005-09-20, 7:02 pm |
| Dear all,
I am developing a multi-threaded daemon application and I have a
question about signal handling.
My strategy for signal handling is the following one:
1) block all of the signals using pthread_sigmask()
2) use sigaction() to ignore SIGHUP, SIGINT, SIGQUIT, SIGPIPE
3) use sigaction() to install a signal handler for SIGCHLD (the daemon
forks new processes)
4) use sigaction() to install a signal handler for SIGTERM, SIGBUS,
SIGFPE, SIGILL, SIGSEGV, SIGSYS, SIGXCPU, SIGXFSZ
5) unblock all of the signals using pthread_sigmask()
The question is, given that in the signal handler installed for
SIGTERM, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGSYS, SIGXCPU, SIGXFSZ I
can only restrict myself to async signal safe calls, how can I safely
perform clenup before calling _exit() ?
I need to do many things, including freeing some malloced memory, but I
can't since there are just a few async signal safe functions I can
safely take advantage of inside the signal handler.
The possibility of just setting a flag of type volatile sig_atomic_t is
ruled out by the fact that, with the exception of SIGTERM, these
signals require the signal handler to _exit().
Also, I believe that siglongjmp() is not a viable solution either,
again the handler should only _exit().
The question is, it seems to me that the only remaining solution is the
use a dedicated thread for cleanup, to be used as follows.
The thread starts and blocks in a call to sem_wait(). It then blocks
indefinitely, until in the signal handler sem_post() is called (this is
async signal safe). The thread then proceeds with the application
cleanup code, while the signal handler is blocked in a call to recv(),
recfrom() or read() from a previously created pipe. When the thread is
done, it calls send(), sendto() or write() and immediately calls
pthread_exit(). The signal handler then proceeds to _exit().
Another solution for the thread to signal that it is done, could be the
use of mkdir() in the thread before exiting and a test using chdir()
in the signal handler, followed by a call to rmdir() before _exit().
All of these functions are async signal safe.
Is this correct? Is there a better way?
Thanks in advance, and best regards.
Massimo
--
****************************************
****************************************
***********************
_Massimo
Cafaro, Ph.D.__ __ __ __ __ __ __ _Center for Advanced Computational
Technologies (CACT)
_Assistant Professor __ __ __ __ __ __ __ __ __ _National
Nanotechnology Laboratory (NNL) of INFM
_University of Lecce, Italy_ _ __ __ __ __ __ _SPACI Consortium_
_Faculty of Engineering_ __ __ __ _ __ __ __ _Voice_ +39 0832 297371_ _
_Via per Monteroni __ _ __ __ __ __ __ __ __ __ _Fax_ __ _+39 0832 297279_
_73100 Lecce, Italy _ __ __ __ __ __ __ __ __ __ _Web _ _
http://sara.unile.it/~cafaro __ __ __ __ _
_E-mail massimo.cafaro@unile.it_ __ _cafaro@cacr.caltech.edu
****************************************
****************************************
***********************
| |
| Pascal Bourguignon 2005-09-21, 6:59 pm |
| Massimo Cafaro <massimo.cafaro@unile.it> writes:
> [...]
> The question is, it seems to me that the only remaining solution is
> the use a dedicated thread for cleanup, to be used as follows.
I would do it this way too.
> The thread starts and blocks in a call to sem_wait(). It then blocks
> indefinitely, until in the signal handler sem_post() is called (this
> is async signal safe). The thread then proceeds with the application
> cleanup code, while the signal handler is blocked in a call to recv(),
> recfrom() or read() from a previously created pipe. When the thread is
> done, it calls send(), sendto() or write() and immediately calls
> pthread_exit(). The signal handler then proceeds to _exit().
I would leave the signal handler after sem_post, and call _exit in the
thread. AFAIK it doesn't matter, since it's done in the same process
anyways.
> Another solution for the thread to signal that it is done, could be
> the use of mkdir() in the thread before exiting and a test using
> chdir() in the signal handler, followed by a call to rmdir() before
> _exit().
>
> All of these functions are async signal safe.
> Is this correct? Is there a better way?
> Thanks in advance, and best regards.
--
__Pascal Bourguignon__ http://www.informatimago.com/
Until real software engineering is developed, the next best practice
is to develop with a dynamic system that has extreme late binding in
all aspects. The first system to really do this in an important way
is Lisp. -- Alan Kay
| |
| Ravi Uday 2005-09-22, 7:56 am |
|
Massimo Cafaro wrote:
> Dear all,
>
> I am developing a multi-threaded daemon application and I have a
> question about signal handling.
> My strategy for signal handling is the following one:
>
> 1) block all of the signals using pthread_sigmask()
> 2) use sigaction() to ignore SIGHUP, SIGINT, SIGQUIT, SIGPIPE
> 3) use sigaction() to install a signal handler for SIGCHLD (the daemon
> forks new processes)
> 4) use sigaction() to install a signal handler for SIGTERM, SIGBUS,
> SIGFPE, SIGILL, SIGSEGV, SIGSYS, SIGXCPU, SIGXFSZ
> 5) unblock all of the signals using pthread_sigmask()
>
> The question is, given that in the signal handler installed for SIGTERM,
> SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGSYS, SIGXCPU, SIGXFSZ I can only
> restrict myself to async signal safe calls, how can I safely perform
> clenup before calling _exit() ?
>
Have you tried looking at -
pthread_cleanup_push/pthread_cleanup_pop
Just doing pthread_cancel is a bad thing to do IMO.
> I need to do many things, including freeing some malloced memory, but I
> can't since there are just a few async signal safe functions I can
> safely take advantage of inside the signal handler.
>
> The possibility of just setting a flag of type volatile sig_atomic_t is
> ruled out by the fact that, with the exception of SIGTERM, these signals
> require the signal handler to _exit().
>
> Also, I believe that siglongjmp() is not a viable solution either, again
> the handler should only _exit().
>
> The question is, it seems to me that the only remaining solution is the
> use a dedicated thread for cleanup, to be used as follows.
Yup, thats a viable option, have a dedicated task which does
cleaning upon receiving a SIGCHLD.
>
> The thread starts and blocks in a call to sem_wait(). It then blocks
> indefinitely, until in the signal handler sem_post() is called (this is
> async signal safe). The thread then proceeds with the application
> cleanup code, while the signal handler is blocked in a call to recv(),
> recfrom() or read() from a previously created pipe. When the thread is
> done, it calls send(), sendto() or write() and immediately calls
> pthread_exit(). The signal handler then proceeds to _exit().
>
> Another solution for the thread to signal that it is done, could be the
> use of mkdir() in the thread before exiting and a test using chdir() in
> the signal handler, followed by a call to rmdir() before _exit().
>
mkdir !! no comments
- Ravi
> All of these functions are async signal safe.
> Is this correct? Is there a better way?
> Thanks in advance, and best regards.
>
> Massimo
>
| |
| Massimo Cafaro 2005-09-22, 6:58 pm |
| On 2005-09-22 15:15:28 +0200, Ravi Uday <raviuday@gmail.com> said:
>
>
> Massimo Cafaro wrote:
>
>
> Have you tried looking at -
>
> pthread_cleanup_push/pthread_cleanup_pop
>
> Just doing pthread_cancel is a bad thing to do IMO.
Yes, I know and use these functions in my threaded code when needed,
but the question is, to the best of my knowledge a cleanup handler
installed by pthread_cleanup_push() and not yet removed by
pthread_cleanup_pop() will be invoked when calling pthread_exit() or
pthread_cancel(), not when calling _exit() which is the only way to
exit correctly a signal handler for the signals I am interested in.
Moreover, the signal handler itself is not being created by a call to
pthread_create(). Also, the function pthread_cleanup_push() is not
async signal safe, so I can not call it inside the signal handler.
Am I wrong ?
>
>
>
> Yup, thats a viable option, have a dedicated task which does
> cleaning upon receiving a SIGCHLD.
Why SIGCHLD? The kernel will deliver to my application SIGCHLD very
rarely (it is even possible that my application never forks a new
process).
>
> mkdir !! no comments
>
>
> - Ravi
mmhhh... I do not see any kind of problem in the use of mkdir() /
chdir() since these are actually async signal safe and can thus be
safely called from a signal handler. The same applies to the creation
of a pipe and the use of read() / write() or to the sockets based
solution.
Is there any technical reason to avoid the use of mkdir() / chdir() or
is it just a matter of personal preference?
Thank you,
Massimo
[color=darkred]
>
--
****************************************
****************************************
***********************
_Massimo
Cafaro, Ph.D.__ __ __ __ __ __ __ _Center for Advanced Computational
Technologies (CACT)
_Assistant Professor __ __ __ __ __ __ __ __ __ _National
Nanotechnology Laboratory (NNL) of INFM
_University of Lecce, Italy_ _ __ __ __ __ __ _SPACI Consortium_
_Faculty of Engineering_ __ __ __ _ __ __ __ _Voice_ +39 0832 297371_ _
_Via per Monteroni __ _ __ __ __ __ __ __ __ __ _Fax_ __ _+39 0832 297279_
_73100 Lecce, Italy _ __ __ __ __ __ __ __ __ __ _Web _ _
http://sara.unile.it/~cafaro __ __ __ __ _
_E-mail massimo.cafaro@unile.it_ __ _cafaro@cacr.caltech.edu
****************************************
****************************************
***********************
| |
| Massimo Cafaro 2005-09-22, 6:58 pm |
| On 2005-09-21 15:46:33 +0200, Pascal Bourguignon <spam@mouse-potato.com> said:
> Massimo Cafaro <massimo.cafaro@unile.it> writes:
>
> I would do it this way too.
>
>
> I would leave the signal handler after sem_post, and call _exit in the
> thread. AFAIK it doesn't matter, since it's done in the same process
> anyways.
Thank you for the interesting suggestion, this is an intriguing option.
[color=darkred]
>
>
--
****************************************
****************************************
***********************
_Massimo
Cafaro, Ph.D.__ __ __ __ __ __ __ _Center for Advanced Computational
Technologies (CACT)
_Assistant Professor __ __ __ __ __ __ __ __ __ _National
Nanotechnology Laboratory (NNL) of INFM
_University of Lecce, Italy_ _ __ __ __ __ __ _SPACI Consortium_
_Faculty of Engineering_ __ __ __ _ __ __ __ _Voice_ +39 0832 297371_ _
_Via per Monteroni __ _ __ __ __ __ __ __ __ __ _Fax_ __ _+39 0832 297279_
_73100 Lecce, Italy _ __ __ __ __ __ __ __ __ __ _Web _ _
http://sara.unile.it/~cafaro __ __ __ __ _
_E-mail massimo.cafaro@unile.it_ __ _cafaro@cacr.caltech.edu
****************************************
****************************************
***********************
|
|
|
|
|