From d0f5240ca9021bffadfe9a3c5584513cfabaa288 Mon Sep 17 00:00:00 2001 From: Jeff Trawick Date: Sat, 13 Dec 2003 19:00:56 +0000 Subject: [PATCH] update leader, threadpool, and worker MPMs to return MPM state from ap_mpm_query() git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@102045 13f79535-47bb-0310-9956-ffa450edef68 --- server/mpm/experimental/leader/leader.c | 27 ++++++++++++-- .../mpm/experimental/threadpool/threadpool.c | 26 ++++++++++++-- server/mpm/worker/worker.c | 35 ++++++++++++++++--- 3 files changed, 80 insertions(+), 8 deletions(-) diff --git a/server/mpm/experimental/leader/leader.c b/server/mpm/experimental/leader/leader.c index 01f8bde87d..2d4950d1a2 100644 --- a/server/mpm/experimental/leader/leader.c +++ b/server/mpm/experimental/leader/leader.c @@ -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); } @@ -496,6 +502,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 @@ -509,7 +516,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; @@ -1056,6 +1063,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(); ap_fatal_signal_child_setup(ap_server_conf); apr_pool_create(&pchild, pconf); @@ -1133,6 +1144,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) { @@ -1505,6 +1518,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; } @@ -1519,12 +1533,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, @@ -1572,8 +1588,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: @@ -1679,6 +1697,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) { @@ -1773,7 +1793,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, diff --git a/server/mpm/experimental/threadpool/threadpool.c b/server/mpm/experimental/threadpool/threadpool.c index 281056d585..29931943a0 100644 --- a/server/mpm/experimental/threadpool/threadpool.c +++ b/server/mpm/experimental/threadpool/threadpool.c @@ -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); } @@ -572,6 +578,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 @@ -585,7 +592,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; @@ -1272,6 +1279,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(); ap_fatal_signal_child_setup(ap_server_conf); apr_pool_create(&pchild, pconf); @@ -1350,6 +1360,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) { @@ -1755,6 +1767,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; } @@ -1769,12 +1782,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, @@ -1822,8 +1837,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: @@ -1934,6 +1951,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) { @@ -2028,7 +2047,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, diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c index f918887182..5366a0446c 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -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); } @@ -411,6 +417,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 @@ -424,7 +431,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; @@ -710,7 +717,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, rv, (const server_rec *) ap_server_conf, @@ -1063,6 +1070,11 @@ static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy) * "life_status" is almost right, but it's in the worker's structure, and * the name could be clearer. gla */ +/* + while (1) { + apr_sleep(apr_time_from_sec(10)); + } +*/ apr_thread_exit(thd, APR_SUCCESS); return NULL; } @@ -1146,6 +1158,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(); ap_fatal_signal_child_setup(ap_server_conf); apr_pool_create(&pchild, pconf); @@ -1224,6 +1239,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) { @@ -1627,6 +1644,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; } @@ -1641,12 +1659,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, @@ -1694,8 +1714,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: @@ -1799,6 +1821,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) { @@ -1893,7 +1917,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, -- 2.50.1