]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Add AP_MPMQ_MPM_STATE function code for ap_mpm_query.
authorJeff Trawick <trawick@apache.org>
Sat, 27 Dec 2003 13:18:57 +0000 (13:18 +0000)
committerJeff Trawick <trawick@apache.org>
Sat, 27 Dec 2003 13:18:57 +0000 (13:18 +0000)
(not currently supported for Win32, BeOS, or OS/2 MPMs)

Submitted by: Jeff Trawick, Brad Nicholes
Reviewed by: stoddard, jerenkrantz

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/APACHE_2_0_BRANCH@102125 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
include/ap_mpm.h
server/mpm/experimental/leader/leader.c
server/mpm/experimental/threadpool/threadpool.c
server/mpm/netware/mpm_netware.c
server/mpm/prefork/prefork.c
server/mpm/worker/worker.c

diff --git a/CHANGES b/CHANGES
index 0e944585f654ff6ea3d0d8dd2aaad5a96c177980..02135308235035711538b3ede8263e4e87c34b55 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,9 @@
 Changes with Apache 2.0.49
 
+  *) Add AP_MPMQ_MPM_STATE function code for ap_mpm_query. (Not yet
+     supported for BeOS, OS/2, or Win32 MPMs.)  [Jeff Trawick,
+     Brad Nicholes]
+
   *) Add mod_status hook to allow modules to add to the mod_status
      report.  [Joe Orton]
 
diff --git a/STATUS b/STATUS
index f3719b06598d1d93ab612c8e5e8a884e6c7463c8..88b9f76ebcbea3706cd334bdf35389c00c0eef26 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -1,5 +1,5 @@
 APACHE 2.0 STATUS:                                              -*-text-*-
-Last modified at [$Date: 2003/12/27 12:11:37 $]
+Last modified at [$Date: 2003/12/27 13:18:56 $]
 
 Release:
 
@@ -162,19 +162,11 @@ PATCHES TO BACKPORT FROM 2.1
       modules/metadata/mod_expires.c r1.45
       +1: ken, stoddard, rederpj
 
-    * PREREQ for a couple of fixes (mod_cgid daemon restart, stranded
-      piped logger processes) - ap_mpm_query(AP_MPMQ_MPM_STATE)
+    * PREREQ for another fix (stranded piped logger processes) - 
+      ap_mpm_query(AP_MPMQ_MPM_STATE)
       No updates are available at present for the BeOS or OS/2 MPMs,
       but that is not a showstopper for the other changes.
 
-        include/ap_mpm.h r1.36
-        server/mpm/prefork/prefork.c r1.284
-        server/mpm/worker/worker.c r1.142,r1.143
-        server/mpm/experimental/leader/leader.c r1.35
-        server/mpm/experimental/threadpool/threadpool.c r1.23
-        server/mpm/netware/mpm_netware.c r1.78
-      +1: trawick, stoddard, jerenkrantz
-
         server/mpm/winnt/mpm_winnt.c r1.303
         server/mpm/winnt/mpm_winnt.h r1.44
         server/mpm/winnt/child.c r1.21
index 5896cbe97613f4cb4a4c299646f39de2d6378ba4..2b726f8080f602d7850df6e2de912fd43c06d056 100644 (file)
@@ -160,6 +160,11 @@ AP_DECLARE(apr_status_t) ap_os_create_privileged_process(
                                       /* an MPM is using a dynamic #  */
                                       /* threads or daemons.          */
 
+/* Values returned 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 @@ AP_DECLARE(apr_status_t) ap_os_create_privileged_process(
 #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 cb022943d71023f79269ec4c90b253fbdc1017f4..92d3fd9a9393490cf240f721fa56294fcf784d71 100644 (file)
@@ -166,6 +166,7 @@ static int start_thread_may_exit = 0;
 static int requests_this_child;
 static int num_listensocks = 0;
 static int resource_shortage = 0;
+static int mpm_state = AP_MPMQ_STARTING;
 
 typedef struct worker_wakeup_info worker_wakeup_info;
 
@@ -400,6 +401,7 @@ static void signal_threads(int mode)
         return;
     }
     terminate_mode = mode;
+    mpm_state = AP_MPMQ_STOPPING;
     workers_may_exit = 1;
 
     worker_stack_term(idle_worker_stack);
@@ -444,6 +446,9 @@ AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
         case AP_MPMQ_MAX_DAEMONS:
             *result = ap_daemons_limit;
             return APR_SUCCESS;
+        case AP_MPMQ_MPM_STATE:
+            *result = mpm_state;
+            return APR_SUCCESS;
     }
     return APR_ENOTIMPL;
 }
@@ -452,6 +457,7 @@ AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
 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);
     }
@@ -523,6 +529,7 @@ ap_generation_t volatile ap_my_generation;
 
 static void ap_start_shutdown(void)
 {
+    mpm_state = AP_MPMQ_STOPPING;
     if (shutdown_pending == 1) {
         /* Um, is this _probably_ not an error, if the user has
          * tried to do a shutdown twice quickly, so we won't
@@ -536,7 +543,7 @@ static void ap_start_shutdown(void)
 /* do a graceful restart if graceful == 1 */
 static void ap_start_restart(int graceful)
 {
-
+    mpm_state = AP_MPMQ_STOPPING;
     if (restart_pending == 1) {
         /* Probably not an error - don't bother reporting it */
         return;
@@ -1104,6 +1111,10 @@ static void child_main(int child_num_arg)
     apr_threadattr_t *thread_attr;
     apr_thread_t *start_thread_id;
 
+    mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
+                                  * child initializes
+                                  */
+
     ap_my_pid = getpid();
     apr_pool_create(&pchild, pconf);
 
@@ -1180,6 +1191,8 @@ static void child_main(int child_num_arg)
         clean_child_exit(APEXIT_CHILDFATAL);
     }
 
+    mpm_state = AP_MPMQ_RUNNING;
+
     /* If we are only running in one_process mode, we will want to
      * still handle signals. */
     if (one_process) {
@@ -1551,6 +1564,7 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
     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;
     }
 
@@ -1565,12 +1579,14 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
             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,
@@ -1618,8 +1634,10 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
                apr_proc_mutex_defname());
 #endif
     restart_pending = shutdown_pending = 0;
+    mpm_state = AP_MPMQ_RUNNING;
 
     server_main_loop(remaining_children_to_start);
+    mpm_state = AP_MPMQ_STOPPING;
 
     if (shutdown_pending) {
         /* Time to gracefully shut down:
@@ -1725,6 +1743,8 @@ static int leader_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
     ap_directive_t *max_clients = NULL;
     apr_status_t rv;
 
+    mpm_state = AP_MPMQ_STARTING;
+
     /* make sure that "ThreadsPerChild" gets set before "MaxClients" */
     for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) {
         if (strncasecmp(pdir->directive, "ThreadsPerChild", 15) == 0) {
@@ -1819,7 +1839,10 @@ static void leader_hooks(apr_pool_t *p)
     one_process = 0;
 
     ap_hook_open_logs(leader_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE);
-    ap_hook_pre_config(leader_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(leader_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
 }
 
 static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy,
index a2d670eed9603daef25b1ce0390b94d93cdc9952..ff78141377c57ad01e00c03d985aa1495121d7b7 100644 (file)
@@ -173,6 +173,7 @@ static int listener_may_exit = 0;
 static int requests_this_child;
 static int num_listensocks = 0;
 static int resource_shortage = 0;
+static int mpm_state = AP_MPMQ_STARTING;
 
 /* The structure used to pass unique initialization info to each thread */
 typedef struct {
@@ -466,6 +467,7 @@ static void signal_threads(int mode)
         return;
     }
     terminate_mode = mode;
+    mpm_state = AP_MPMQ_STOPPING;
 
     /* in case we weren't called from the listener thread, wake up the
      * listener thread
@@ -521,6 +523,9 @@ AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
         case AP_MPMQ_MAX_DAEMONS:
             *result = ap_daemons_limit;
             return APR_SUCCESS;
+        case AP_MPMQ_MPM_STATE:
+            *result = mpm_state;
+            return APR_SUCCESS;
     }
     return APR_ENOTIMPL;
 }
@@ -529,6 +534,7 @@ AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
 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);
     }
@@ -599,6 +605,7 @@ ap_generation_t volatile ap_my_generation;
 
 static void ap_start_shutdown(void)
 {
+    mpm_state = AP_MPMQ_STOPPING;
     if (shutdown_pending == 1) {
         /* Um, is this _probably_ not an error, if the user has
          * tried to do a shutdown twice quickly, so we won't
@@ -612,7 +619,7 @@ static void ap_start_shutdown(void)
 /* do a graceful restart if graceful == 1 */
 static void ap_start_restart(int graceful)
 {
-
+    mpm_state = AP_MPMQ_STOPPING;
     if (restart_pending == 1) {
         /* Probably not an error - don't bother reporting it */
         return;
@@ -1319,6 +1326,9 @@ static void child_main(int child_num_arg)
     apr_threadattr_t *thread_attr;
     apr_thread_t *start_thread_id;
 
+    mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
+                                   * child initializes
+                                   */
     ap_my_pid = getpid();
     apr_pool_create(&pchild, pconf);
 
@@ -1396,6 +1406,8 @@ static void child_main(int child_num_arg)
         clean_child_exit(APEXIT_CHILDFATAL);
     }
 
+    mpm_state = AP_MPMQ_RUNNING;
+    
     /* If we are only running in one_process mode, we will want to
      * still handle signals. */
     if (one_process) {
@@ -1800,6 +1812,7 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
     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;
     }
 
@@ -1814,12 +1827,14 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
             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,
@@ -1867,8 +1882,10 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
                apr_proc_mutex_defname());
 #endif
     restart_pending = shutdown_pending = 0;
+    mpm_state = AP_MPMQ_RUNNING;
 
     server_main_loop(remaining_children_to_start);
+    mpm_state = AP_MPMQ_STOPPING;
 
     if (shutdown_pending) {
         /* Time to gracefully shut down:
@@ -1979,6 +1996,8 @@ static int worker_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
     ap_directive_t *max_clients = NULL;
     apr_status_t rv;
 
+    mpm_state = AP_MPMQ_STARTING;
+    
     /* make sure that "ThreadsPerChild" gets set before "MaxClients" */
     for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) {
         if (strncasecmp(pdir->directive, "ThreadsPerChild", 15) == 0) {
@@ -2073,7 +2092,10 @@ static void threadpool_hooks(apr_pool_t *p)
     one_process = 0;
 
     ap_hook_open_logs(worker_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE);
-    ap_hook_pre_config(worker_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(worker_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
 }
 
 static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy,
index 3bd41f309a8d6efd4d9f3d8528c40a0a2c8c0cbd..a2b57d50b5b254c0525d8c384fb3353001cb3999 100644 (file)
@@ -154,6 +154,7 @@ static int ap_threads_to_start=0;
 static int ap_threads_min_free=0;
 static int ap_threads_max_free=0;
 static int ap_threads_limit=0;
+static int mpm_state = AP_MPMQ_STARTING;
 
 /*
  * The max child slot ever assigned, preserved across restarts.  Necessary
@@ -268,6 +269,9 @@ AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
         case AP_MPMQ_MAX_DAEMONS:
             *result = 1;
             return APR_SUCCESS;
+        case AP_MPMQ_MPM_STATE:
+            *result = mpm_state;
+            return APR_SUCCESS;
     }
     return APR_ENOTIMPL;
 }
@@ -946,6 +950,7 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
 #endif
     show_server_data();
 
+    mpm_state = AP_MPMQ_RUNNING;
     while (!restart_pending && !shutdown_pending) {
         perform_idle_server_maintenance(pconf);
         if (show_settings)
@@ -953,6 +958,7 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
         apr_thread_yield();
         apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL);
     }
+    mpm_state = AP_MPMQ_STOPPING;
 
 
     /* Shutdown the listen sockets so that we don't get stuck in a blocking call. 
@@ -998,6 +1004,8 @@ static int netware_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp
     int debug;
     char *addrname = NULL;
 
+    mpm_state = AP_MPMQ_STARTING;
+
     debug = ap_exists_config_define("DEBUG");
 
     is_graceful = 0;
index 06b8aa20c93e6e44adeaba7c705c73e3ab0ca802..cb56c3f66bad276f28313e32adbe23d27c9fb82d 100644 (file)
@@ -141,7 +141,7 @@ static int ap_daemons_limit=0;      /* MaxClients */
 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 chdir_for_gprof(void)
 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 @@ AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
         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 @@ static void child_main(int child_num_arg)
     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 @@ static void child_main(int child_num_arg)
         pollset[i].reqevents = APR_POLLIN;
     }
 
+    mpm_state = AP_MPMQ_RUNNING;
+    
     bucket_alloc = apr_bucket_alloc_create(pchild);
 
     while (!die_now) {
@@ -969,6 +980,7 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
     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 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
             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 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
 #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 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
        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 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
 #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 @@ static int prefork_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp
     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 @@ static void prefork_hooks(apr_pool_t *p)
 #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) 
index df6c7e6bbca71ce26092060860e914c6020e9ffb..bf5a1a36cb526e62e35174093daef8f18dbf918c 100644 (file)
@@ -175,6 +175,7 @@ static int num_listensocks = 0;
 static int resource_shortage = 0;
 static fd_queue_t *worker_queue;
 static fd_queue_info_t *worker_queue_info;
+static int mpm_state = AP_MPMQ_STARTING;
 
 /* The structure used to pass unique initialization info to each thread */
 typedef struct {
@@ -303,6 +304,7 @@ static void signal_threads(int mode)
         return;
     }
     terminate_mode = mode;
+    mpm_state = AP_MPMQ_STOPPING;
 
     /* in case we weren't called from the listener thread, wake up the
      * listener thread
@@ -360,6 +362,9 @@ AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
         case AP_MPMQ_MAX_DAEMONS:
             *result = ap_daemons_limit;
             return APR_SUCCESS;
+        case AP_MPMQ_MPM_STATE:
+            *result = mpm_state;
+            return APR_SUCCESS;
     }
     return APR_ENOTIMPL;
 }
@@ -368,6 +373,7 @@ AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
 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);
     }
@@ -438,6 +444,7 @@ ap_generation_t volatile ap_my_generation;
 
 static void ap_start_shutdown(void)
 {
+    mpm_state = AP_MPMQ_STOPPING;
     if (shutdown_pending == 1) {
         /* Um, is this _probably_ not an error, if the user has
          * tried to do a shutdown twice quickly, so we won't
@@ -451,7 +458,7 @@ static void ap_start_shutdown(void)
 /* do a graceful restart if graceful == 1 */
 static void ap_start_restart(int graceful)
 {
-
+    mpm_state = AP_MPMQ_STOPPING;
     if (restart_pending == 1) {
         /* Probably not an error - don't bother reporting it */
         return;
@@ -765,7 +772,7 @@ static void *listener_thread(apr_thread_t *thd, void * dummy)
                         continue;
                     }
 
-                    /* apr_poll() will only return errors in catastrophic
+                    /* apr_pollset_poll() will only return errors in catastrophic
                      * circumstances. Let's try exiting gracefully, for now. */
                     ap_log_error(APLOG_MARK, APLOG_ERR, ret, (const server_rec *)
                                  ap_server_conf, "apr_poll: (listen)");
@@ -1190,6 +1197,9 @@ static void child_main(int child_num_arg)
     apr_threadattr_t *thread_attr;
     apr_thread_t *start_thread_id;
 
+    mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
+                                   * child initializes
+                                   */
     ap_my_pid = getpid();
     apr_pool_create(&pchild, pconf);
 
@@ -1267,6 +1277,8 @@ static void child_main(int child_num_arg)
         clean_child_exit(APEXIT_CHILDFATAL);
     }
 
+    mpm_state = AP_MPMQ_RUNNING;
+
     /* If we are only running in one_process mode, we will want to
      * still handle signals. */
     if (one_process) {
@@ -1669,6 +1681,7 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
     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;
     }
 
@@ -1683,12 +1696,14 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
             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,
@@ -1736,8 +1751,10 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
                apr_proc_mutex_defname());
 #endif
     restart_pending = shutdown_pending = 0;
-
+    mpm_state = AP_MPMQ_RUNNING;
+    
     server_main_loop(remaining_children_to_start);
+    mpm_state = AP_MPMQ_STOPPING;
 
     if (shutdown_pending) {
         /* Time to gracefully shut down:
@@ -1841,6 +1858,8 @@ static int worker_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
     ap_directive_t *max_clients = NULL;
     apr_status_t rv;
 
+    mpm_state = AP_MPMQ_STARTING;
+
     /* make sure that "ThreadsPerChild" gets set before "MaxClients" */
     for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) {
         if (strncasecmp(pdir->directive, "ThreadsPerChild", 15) == 0) {
@@ -1935,7 +1954,10 @@ static void worker_hooks(apr_pool_t *p)
     one_process = 0;
 
     ap_hook_open_logs(worker_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE);
-    ap_hook_pre_config(worker_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(worker_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
 }
 
 static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy,