Index: include/ap_mpm.h =================================================================== RCS file: /home/cvs/httpd-2.0/include/ap_mpm.h,v --- include/ap_mpm.h 3 Feb 2003 17:31:29 -0000 1.33.2.1 +++ include/ap_mpm.h 20 Nov 2003 21:54:10 -0000 @@ -160,6 +160,11 @@ /* an MPM is using a dynamic # */ /* threads or daemons. */ +/* Values for AP_MPMQ_MPM_STATE */ +#define AP_MPMQ_STARTING 0 +#define AP_MPMQ_RUNNING 1 +#define AP_MPMQ_STOPPING 2 + #define AP_MPMQ_MAX_DAEMON_USED 1 /* Max # of daemons used so far */ #define AP_MPMQ_IS_THREADED 2 /* MPM can do threading */ #define AP_MPMQ_IS_FORKED 3 /* MPM can do forking */ @@ -172,7 +177,7 @@ #define AP_MPMQ_MAX_SPARE_THREADS 10 /* Max # of spare threads */ #define AP_MPMQ_MAX_REQUESTS_DAEMON 11 /* Max # of requests per daemon */ #define AP_MPMQ_MAX_DAEMONS 12 /* Max # of daemons by config */ - +#define AP_MPMQ_MPM_STATE 13 /* starting, running, stopping */ /** * Query a property of the current MPM. Index: server/log.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/log.c,v --- server/log.c 23 Jun 2003 13:03:59 -0000 1.127.2.4 +++ server/log.c 20 Nov 2003 21:54:10 -0000 @@ -91,6 +91,7 @@ #include "http_log.h" #include "http_main.h" #include "util_time.h" +#include "ap_mpm.h" typedef struct { char *t_name; @@ -791,26 +792,38 @@ { piped_log *pl = data; apr_status_t stats; + int mpm_state; switch (reason) { case APR_OC_REASON_DEATH: case APR_OC_REASON_LOST: - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "piped log program '%s' failed unexpectedly", - pl->program); - pl->pid = NULL; apr_proc_other_child_unregister(pl); - if (pl->program == NULL) { - /* during a restart */ - break; - } - if ((stats = piped_log_spawn(pl)) != APR_SUCCESS) { - /* what can we do? This could be the error log we're having - * problems opening up... */ - char buf[120]; + stats = ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state); + if (stats != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "can't query MPM state; not restarting " + "piped log program '%s'", + pl->program); + } + else if (mpm_state != AP_MPMQ_STOPPING) { ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "piped_log_maintenance: unable to respawn '%s': %s", - pl->program, apr_strerror(stats, buf, sizeof(buf))); + "piped log program '%s' failed unexpectedly", + pl->program); + pl->pid = NULL; + if (pl->program == NULL) { /* XXX how does this work? doesn't a query + * of the MPM state resolve this too? + */ + /* during a restart */ + break; + } + if ((stats = piped_log_spawn(pl)) != APR_SUCCESS) { + /* what can we do? This could be the error log we're having + * problems opening up... */ + char buf[120]; + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "piped_log_maintenance: unable to respawn '%s': %s", + pl->program, apr_strerror(stats, buf, sizeof(buf))); + } } break; Index: server/mpm/prefork/prefork.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/prefork/prefork.c,v --- server/mpm/prefork/prefork.c 5 Sep 2003 19:00:53 -0000 1.272.2.3 +++ server/mpm/prefork/prefork.c 20 Nov 2003 21:54:10 -0000 @@ -141,7 +141,7 @@ static int server_limit = DEFAULT_SERVER_LIMIT; static int first_server_limit; static int changed_limit_at_restart; - +static int mpm_state = AP_MPMQ_STARTING; static ap_pod_t *pod; /* @@ -229,6 +229,8 @@ static void clean_child_exit(int code) __attribute__ ((noreturn)); static void clean_child_exit(int code) { + mpm_state = AP_MPMQ_STOPPING; + if (pchild) { apr_pool_destroy(pchild); } @@ -326,6 +328,9 @@ case AP_MPMQ_MAX_DAEMONS: *result = server_limit; return APR_SUCCESS; + case AP_MPMQ_MPM_STATE: + *result = mpm_state; + return APR_SUCCESS; } return APR_ENOTIMPL; } @@ -550,6 +555,10 @@ apr_status_t rv; apr_bucket_alloc_t *bucket_alloc; + mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this + * child initializes + */ + my_child_num = child_num_arg; ap_my_pid = getpid(); csd = NULL; @@ -601,6 +610,8 @@ pollset[i].reqevents = APR_POLLIN; } + mpm_state = AP_MPMQ_RUNNING; + bucket_alloc = apr_bucket_alloc_create(pchild); while (!die_now) { @@ -969,6 +980,7 @@ if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, "Couldn't create accept lock"); + mpm_state = AP_MPMQ_STOPPING; return 1; } @@ -983,12 +995,14 @@ ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, "Couldn't set permissions on cross-process lock; " "check User and Group directives"); + mpm_state = AP_MPMQ_STOPPING; return 1; } } if (!is_graceful) { if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { + mpm_state = AP_MPMQ_STOPPING; return 1; } /* fix the generation number in the global score; we just got a new, @@ -1041,6 +1055,8 @@ #endif restart_pending = shutdown_pending = 0; + mpm_state = AP_MPMQ_RUNNING; + while (!restart_pending && !shutdown_pending) { int child_slot; apr_exit_why_e exitwhy; @@ -1057,6 +1073,7 @@ if (pid.pid != -1) { processed_status = ap_process_child_status(&pid, exitwhy, status); if (processed_status == APEXIT_CHILDFATAL) { + mpm_state = AP_MPMQ_STOPPING; return 1; } @@ -1123,6 +1140,8 @@ #endif /*TPF */ } + mpm_state = AP_MPMQ_STOPPING; + if (shutdown_pending) { /* Time to gracefully shut down: * Kill child processes, tell them to call child_exit, etc... @@ -1223,6 +1242,8 @@ int no_detach, debug, foreground; apr_status_t rv; + mpm_state = AP_MPMQ_STARTING; + debug = ap_exists_config_define("DEBUG"); if (debug) { @@ -1285,7 +1306,10 @@ #endif ap_hook_open_logs(prefork_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE); - ap_hook_pre_config(prefork_pre_config, NULL, NULL, APR_HOOK_MIDDLE); + /* we need to set the MPM state before other pre-config hooks use MPM query + * to retrieve it, so register as REALLY_FIRST + */ + ap_hook_pre_config(prefork_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); } static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, const char *arg)