Wednesday, October 26, 2005

Ethics of writing a Signal Handler

Signal handlers are generally used incorrectly in the code. I am writing some guidelines for writing a signal handler (This involved comments from Boris and also some hacking with apache.)

1. A signal should do the minimum, like just setting/unsetting a variable. Most often signal handlers interupt execution of a syscal (if its in a interuptable sleep) , and this syscal restarts when signal handler finishes. Now If this signal handler calls the same syscal which was interupted .. we have a "futex" ( I have had some real bad experiences with this .. trust me).

Boris - "On the other hand, if we expect some code to execute right away,
we need to also arrange any blocking system calls to be interrupted by the
signal. By default, some calls like read() are automatically restarted
after the signal handler returns but this behaviour can be changed with
sa_flags in sigaction()."

2. Earlier the implementation of exclog had same sig-handler for both SIGTERM and SIGHUP but If apache calls SIGHUP and then SIGTERM (which it does) in a very short span of time, sig handler for SIGHUP will get interupetd by sig handler of SIGTERM !! .. and as boris explains it "BOOM!! Anything from lock up to infinite loop to smoke and fire may happen."

3. Linux automatically blocks the signal which caused a signal handler to be invoked during the execution of that handler BUT it doesn't block any other signals that may be using the same handler. Luckily, this is easy to achieve with sa_mask in sigaction().

4. In addition to point 1. Sometime when you modify a variable in a signal handler which is later being checked in the main loop for any changes, it is always advisable to declare this global variable as volatile. Coz the compiler seeing that variable is only check in main loop, may optimize so that the vaiable is not loaded from memory everytime its checked. Hence changes by signal handler may not be visible in the loop.


From Apache's point of view -
When Apache is stopping it sends a SIGHUP first and then SIGTERM to all its children ( thats what was also visible in apache modules). And most of the modules catch both these signals to clean up stuff. So, I am not sure why SIGHUP is handled my modules, it can be handled using SIG_ING. For that matter why SIGHUP and SIGTERM are handled when the process is going to die anyways .. and you can't do anything about it.

Why buy a life insurance for self .. if you are going to die ;-).

What if two SIGTERMs appear together, it would cause a futex, and the process will never die.

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home