Jim Jagielski <[EMAIL PROTECTED]> writes:
> PR 8001 reports that we are incorrectly using exit() in clean_child_exit
> when it's called via just_die, which is a signal handler... I'm not
> aware of exit() being a non-recommended option :)
Hmmm, never heard of exit() as a problem. Maybe the point is that it
calls atexit()-registered routines, which can themselves do stuff that
doesn't work in a signal handler? _exit() would avoid that, but then
maybe there is module-related stuff which really needs to be done.
What I have heard of lately (!!!uggh!!!), and what Bill alluded to in
his follow-up to your post, is that clean_child_exit() from a signal
handler, and the calling of child-exit, can cause problems with
certain third-party modules which do stuff which, at least on certain
platforms, doesn't work in a signal handler. (In other words, I don't
know what the &^%^$ the module is doing but when I gave them a patch
which no longer did clean_child_exit() from the SIGUSR1 handler,
segfaults during idle server maintenance-initiated SIGUSR1s went
away.)
This patch is a 1st pass at avoiding those issues. There are a couple
of bogus log entries for testing purposes :)
I'll try to have a look-see at PR 8001 and see what that is.
Index: src/main/http_main.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_main.c,v
retrieving revision 1.535
diff -u -r1.535 http_main.c
--- src/main/http_main.c 2001/04/12 17:49:26 1.535
+++ src/main/http_main.c 2001/09/25 15:37:46
@@ -301,6 +301,7 @@
static server_rec *server_conf;
#ifndef NETWARE
static JMP_BUF APACHE_TLS jmpbuffer;
+static JMP_BUF APACHE_TLS die_jmpbuffer;
#endif
static int sd;
static fd_set listenfds;
@@ -486,6 +487,8 @@
static void clean_child_exit(int code) __attribute__ ((noreturn));
static void clean_child_exit(int code)
{
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
+ "clean_child_exit(%d)", code);
if (pchild) {
ap_child_exit_modules(pchild, server_conf);
ap_destroy_pool(pchild);
@@ -2775,7 +2778,10 @@
exit_after_unblock = 1;
}
else {
- clean_child_exit(0);
+ if (one_process) {
+ clean_child_exit(0);
+ }
+ ap_longjmp(die_jmpbuffer, sig);
}
}
@@ -2785,7 +2791,11 @@
static void usr1_handler(int sig)
{
if (usr1_just_die) {
- just_die(sig);
+ if (alarms_blocked) {
+ exit_after_unblock = 1;
+ return;
+ }
+ ap_longjmp(die_jmpbuffer, sig);
}
deferred_die = 1;
}
@@ -3996,6 +4006,8 @@
break;
if (deferred_die) {
/* we didn't get a socket, and we were told to die */
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, server_conf,
+ "deferred_die (%d)",__LINE__);
clean_child_exit(0);
}
}
@@ -4099,6 +4111,8 @@
usr1_just_die = 1;
if (deferred_die) {
/* ok maybe not, see ya later */
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, server_conf,
+ "deferred_die");
clean_child_exit(0);
}
/* or maybe we missed a signal, you never know on systems
@@ -4297,7 +4311,7 @@
static int make_child(server_rec *s, int slot, time_t now)
{
- int pid;
+ int pid, sig;
if (slot + 1 > max_daemons_limit) {
max_daemons_limit = slot + 1;
@@ -4362,6 +4376,13 @@
* Note that since restart() just notes that a restart has been
* requested there's no race condition here.
*/
+
+ if ((sig = ap_setjmp(die_jmpbuffer)) != 0) {
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, server_conf,
+ "just jumped");
+ clean_child_exit(0);
+ }
+
signal(SIGHUP, just_die);
signal(SIGUSR1, just_die);
signal(SIGTERM, just_die);
--
Jeff Trawick | [EMAIL PROTECTED] | PGP public key at web site:
http://www.geocities.com/SiliconValley/Park/9289/
Born in Roswell... married an alien...