Wednesday, May 17, 2000
It's off to the Races
I was right, there were
race conditions in monnet.
Mark helped me
in locating them and my only comment on the whole thing is: Unix signal
semantics suck. Although Mark assures me that any form synchronization is
nasty, although I still don't see why it has to be so difficult.
To be portable, the only thing you can do in a signal handler is do
a simple assignment to a variable declared as volatile sig_atomic_t.
Anything else could lead to problems. So, in monnet
I now
have:
volatile sig_atomic_t g_sigint = 0; volatile sig_atomic_t g_sighup = 0; volatile sig_atomic_t g_sigchld = 0; static void handler_int() { g_sigint = 1; } static void handler_hup() { g_sighup = 1; } static void handler_chld() { int status; g_sigchld = 1; wait(&status); }
Granted, that isn't proper ANSI C
function headers, but there is no
real consensus as to what signal handlers take (on some systems, a single
integer parameter, others, no parameters, others several parameters) so
that's about the best you can do. I am taking a risk with
handler_chld()
in doing the wait()
but POSIX
lists wait()
as being callable via a signal handler so hey, why not
live on the edge here. Now, elsewhere, the main code:
while(1) { while(1) { s = read( /* ... */ ) if (s <= 0) break; /* ... */ } if (g_sighup) { g_sighup = 0; generate_report(); } if (g_sigchld) { g_sigchld = 0; g_child = 0; } if (g_sigint) break; } /* ... */ static void generate_report(void) { if (g_child != 0) return; g_child = fork(); if (g_child > 0) /* parent resumes */ return; else if (g_child < 0) /* error? just resume */ { g_child = 0; return; } /* ... */ }
SIGINT
just breaks out of the main loop and terminates the program
(with some cleanup). SIGHUP
generates a call to
generate_report()
which creates a new process (if one hasn't
already been created) to generate the actual report.
If I didn't handle SIGCHLD,
I would end up with zombie processes
(lovely in that even if I don't care about the child, I still have to
wait()
for it). Now, it is conceivable that a SIGHUP
sent
at the right time would fail to create a report file, but would only happen
if a previous SIGHUP
had been given to generate a report file and
was just finishing up. But I can live with that.
Mmmmmmmmmmmmm … roasted ants …
I smelled something burning in the Computer Room. That is not a good sign. So I start investigating when I remember I had this same problem last year about this time.
Sure enough, I check the halogen lamp and there are dozens of dead roasted flying ants in the lamp. It's ant mating season again in South Florida and somehow a bunch always manage to get into the house and get roasted by the halogen lamp.
Sigh.