For Programmers: Free Programming Magazines  


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]

 

Author signal handling
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

****************************************
****************************************
***********************


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com