From: Jeff Trawick Date: Wed, 1 Apr 2009 11:53:50 +0000 (+0000) Subject: mpm-query hook: distinguish between DECLINED and APR_ENOTIMPL so that X-Git-Tag: 2.3.3~742 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=23ac01a833c74e3ca1f92f66f295a993ad224d35;p=thirdparty%2Fapache%2Fhttpd.git mpm-query hook: distinguish between DECLINED and APR_ENOTIMPL so that . ap_mpm_query() can return APR_EGENERAL if called too early (for debugging a module) . some hypothetical module which implements the mpm-query hook can bypass the MPM with APR_ENOTIMPL git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@760864 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/ap_mpm.h b/include/ap_mpm.h index 15c37c906f6..d5844a912c7 100644 --- a/include/ap_mpm.h +++ b/include/ap_mpm.h @@ -147,10 +147,14 @@ AP_DECLARE(apr_status_t) ap_os_create_privileged_process( #define AP_MPMQ_HAS_SERF 16 /* MPM can drive serf internally */ /** - * Query a property of the current MPM. + * Query a property of the current MPM. * @param query_code One of APM_MPMQ_* * @param result A location to place the result of the query - * @return APR_SUCCESS or APR_ENOTIMPL + * @return APR_EGENERAL if an mpm-query hook has not been registered; + * APR_SUCCESS or APR_ENOTIMPL otherwise + * @remark The MPM doesn't register the implementing hook until the + * register_hooks hook is called, so modules cannot use ap_mpm_query() + * until after that point. * @fn int ap_mpm_query(int query_code, int *result) */ AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result); diff --git a/include/mpm_common.h b/include/mpm_common.h index ce86ab12bff..511ae1cd7cd 100644 --- a/include/mpm_common.h +++ b/include/mpm_common.h @@ -323,8 +323,11 @@ AP_DECLARE_HOOK(int, drop_privileges, (apr_pool_t * pchild, server_rec * s)) /* pass control to the MPM */ AP_DECLARE_HOOK(int, mpm, (apr_pool_t *pconf, apr_pool_t *plog, server_rec *s)) -/* implement the mpm query function */ -AP_DECLARE_HOOK(apr_status_t, mpm_query, (int query_code, int *result)) +/* implement the ap_mpm_query() function + * The MPM should return OK+APR_ENOTIMPL for any unimplemented query codes; + * modules which intercede for specific query codes should DECLINE for others. + */ +AP_DECLARE_HOOK(int, mpm_query, (int query_code, int *result, apr_status_t *rv)) /* child specified by index has been killed */ AP_DECLARE_HOOK(apr_status_t, mpm_note_child_killed, (int childnum)) @@ -333,7 +336,7 @@ AP_DECLARE_HOOK(apr_status_t, mpm_note_child_killed, (int childnum)) AP_DECLARE_HOOK(apr_status_t, mpm_register_timed_callback, (apr_time_t t, ap_mpm_callback_fn_t *cbfn, void *baton)) -/* get MPM name */ +/* get MPM name (e.g., "prefork" or "event") */ AP_DECLARE_HOOK(const char *,mpm_get_name,(void)) #ifdef __cplusplus diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c index 7671eb2181d..06f07a8cd6f 100644 --- a/server/mpm/event/event.c +++ b/server/mpm/event/event.c @@ -349,59 +349,63 @@ static void signal_threads(int mode) } } -static apr_status_t event_query(int query_code, int *result) +static int event_query(int query_code, int *result, apr_status_t *rv) { + *rv = APR_SUCCESS; switch (query_code) { case AP_MPMQ_MAX_DAEMON_USED: *result = max_daemons_limit; - return APR_SUCCESS; + break; case AP_MPMQ_IS_THREADED: *result = AP_MPMQ_STATIC; - return APR_SUCCESS; + break; case AP_MPMQ_IS_FORKED: *result = AP_MPMQ_DYNAMIC; - return APR_SUCCESS; + break; case AP_MPMQ_IS_ASYNC: *result = 1; - return APR_SUCCESS; + break; case AP_MPMQ_HAS_SERF: *result = 1; - return APR_SUCCESS; + break; case AP_MPMQ_HARD_LIMIT_DAEMONS: *result = server_limit; - return APR_SUCCESS; + break; case AP_MPMQ_HARD_LIMIT_THREADS: *result = thread_limit; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_THREADS: *result = threads_per_child; - return APR_SUCCESS; + break; case AP_MPMQ_MIN_SPARE_DAEMONS: *result = 0; - return APR_SUCCESS; + break; case AP_MPMQ_MIN_SPARE_THREADS: *result = min_spare_threads; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_SPARE_DAEMONS: *result = 0; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_SPARE_THREADS: *result = max_spare_threads; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_REQUESTS_DAEMON: *result = ap_max_requests_per_child; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_DAEMONS: *result = ap_daemons_limit; - return APR_SUCCESS; + break; case AP_MPMQ_MPM_STATE: *result = mpm_state; - return APR_SUCCESS; + break; case AP_MPMQ_GENERATION: *result = my_generation; - return APR_SUCCESS; + break; + default: + *rv = APR_ENOTIMPL; + break; } - return APR_ENOTIMPL; + return OK; } static apr_status_t event_note_child_killed(int childnum) diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c index 7c1b1518c94..3b9d4fd6cbd 100644 --- a/server/mpm/prefork/prefork.c +++ b/server/mpm/prefork/prefork.c @@ -242,53 +242,57 @@ static void accept_mutex_off(void) #define SAFE_ACCEPT(stmt) do {stmt;} while(0) #endif -static apr_status_t prefork_query(int query_code, int *result) +static int prefork_query(int query_code, int *result, apr_status_t *rv) { + *rv = APR_SUCCESS; switch(query_code){ case AP_MPMQ_MAX_DAEMON_USED: *result = ap_daemons_limit; - return APR_SUCCESS; + break; case AP_MPMQ_IS_THREADED: *result = AP_MPMQ_NOT_SUPPORTED; - return APR_SUCCESS; + break; case AP_MPMQ_IS_FORKED: *result = AP_MPMQ_DYNAMIC; - return APR_SUCCESS; + break; case AP_MPMQ_HARD_LIMIT_DAEMONS: *result = server_limit; - return APR_SUCCESS; + break; case AP_MPMQ_HARD_LIMIT_THREADS: *result = HARD_THREAD_LIMIT; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_THREADS: *result = 0; - return APR_SUCCESS; + break; case AP_MPMQ_MIN_SPARE_DAEMONS: *result = ap_daemons_min_free; - return APR_SUCCESS; + break; case AP_MPMQ_MIN_SPARE_THREADS: *result = 0; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_SPARE_DAEMONS: *result = ap_daemons_max_free; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_SPARE_THREADS: *result = 0; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_REQUESTS_DAEMON: *result = ap_max_requests_per_child; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_DAEMONS: *result = server_limit; - return APR_SUCCESS; + break; case AP_MPMQ_MPM_STATE: *result = mpm_state; - return APR_SUCCESS; + break; case AP_MPMQ_GENERATION: *result = my_generation; - return APR_SUCCESS; + break; + default: + *rv = APR_ENOTIMPL; + break; } - return APR_ENOTIMPL; + return OK; } static apr_status_t prefork_note_child_killed(int childnum) diff --git a/server/mpm/simple/simple_api.c b/server/mpm/simple/simple_api.c index c6e271c504d..24b4a6af310 100644 --- a/server/mpm/simple/simple_api.c +++ b/server/mpm/simple/simple_api.c @@ -41,71 +41,60 @@ static int simple_run(apr_pool_t * pconf, apr_pool_t * plog, server_rec * s) return simple_main_loop(sc); } -static apr_status_t simple_query(int query_code, int *result) +static int simple_query(int query_code, int *result, apr_status_t *rv) { simple_core_t *sc = simple_core_get(); + *rv = APR_SUCCESS; switch (query_code) { case AP_MPMQ_IS_THREADED: *result = AP_MPMQ_STATIC; - return APR_SUCCESS; break; case AP_MPMQ_IS_FORKED: *result = AP_MPMQ_DYNAMIC; - return APR_SUCCESS; break; case AP_MPMQ_IS_ASYNC: *result = 1; - return APR_SUCCESS; break; case AP_MPMQ_MAX_DAEMON_USED: *result = sc->procmgr.proc_count; - return APR_SUCCESS; break; case AP_MPMQ_HARD_LIMIT_DAEMONS: *result = sc->procmgr.proc_count; - return APR_SUCCESS; break; case AP_MPMQ_HARD_LIMIT_THREADS: *result = sc->procmgr.thread_count; - return APR_SUCCESS; break; case AP_MPMQ_MAX_THREADS: *result = sc->procmgr.thread_count; - return APR_SUCCESS; break; case AP_MPMQ_MAX_SPARE_DAEMONS: *result = sc->procmgr.proc_count; - return APR_SUCCESS; break; case AP_MPMQ_MIN_SPARE_DAEMONS: *result = sc->procmgr.proc_count; - return APR_SUCCESS; break; case AP_MPMQ_MIN_SPARE_THREADS: case AP_MPMQ_MAX_SPARE_THREADS: *result = sc->procmgr.thread_count; - return APR_SUCCESS; break; case AP_MPMQ_MAX_REQUESTS_DAEMON: *result = sc->procmgr.max_requests_per_child; - return APR_SUCCESS; break; case AP_MPMQ_MAX_DAEMONS: *result = sc->procmgr.proc_count; - return APR_SUCCESS; break; case AP_MPMQ_MPM_STATE: *result = sc->mpm_state; - return APR_SUCCESS; + break; case AP_MPMQ_GENERATION: *result = 0; - return APR_SUCCESS; + break; default: + *rv = APR_ENOTIMPL; break; } - - return APR_ENOTIMPL; + return OK; } static const char * diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c index 753543c97f6..dcbf00d5ea1 100644 --- a/server/mpm/winnt/mpm_winnt.c +++ b/server/mpm/winnt/mpm_winnt.c @@ -893,53 +893,57 @@ apr_array_header_t *mpm_new_argv; * service after we preflight the config. */ -static apr_status_t winnt_query(int query_code, int *result) +static int winnt_query(int query_code, int *result, apr_status_t *rv) { - switch(query_code){ + *rv = APR_SUCCESS; + switch (query_code) { case AP_MPMQ_MAX_DAEMON_USED: *result = MAXIMUM_WAIT_OBJECTS; - return APR_SUCCESS; + break; case AP_MPMQ_IS_THREADED: *result = AP_MPMQ_STATIC; - return APR_SUCCESS; + break; case AP_MPMQ_IS_FORKED: *result = AP_MPMQ_NOT_SUPPORTED; - return APR_SUCCESS; + break; case AP_MPMQ_HARD_LIMIT_DAEMONS: *result = HARD_SERVER_LIMIT; - return APR_SUCCESS; + break; case AP_MPMQ_HARD_LIMIT_THREADS: *result = thread_limit; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_THREADS: *result = ap_threads_per_child; - return APR_SUCCESS; + break; case AP_MPMQ_MIN_SPARE_DAEMONS: *result = 0; - return APR_SUCCESS; + break; case AP_MPMQ_MIN_SPARE_THREADS: *result = 0; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_SPARE_DAEMONS: *result = 0; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_SPARE_THREADS: *result = 0; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_REQUESTS_DAEMON: *result = ap_max_requests_per_child; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_DAEMONS: *result = 0; - return APR_SUCCESS; + break; case AP_MPMQ_MPM_STATE: *result = winnt_mpm_state; - return APR_SUCCESS; + break; case AP_MPMQ_GENERATION: *result = my_generation; - return APR_SUCCESS; + break; + default: + *rv = APR_ENOTIMPL; + break; } - return APR_ENOTIMPL; + return OK; } static const char *winnt_get_name(void) diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c index 7777396ec65..9971162b155 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -305,53 +305,57 @@ static void signal_threads(int mode) } } -static apr_status_t worker_query(int query_code, int *result) +static int worker_query(int query_code, int *result, apr_status_t *rv) { - switch(query_code){ + *rv = APR_SUCCESS; + switch (query_code) { case AP_MPMQ_MAX_DAEMON_USED: *result = max_daemons_limit; - return APR_SUCCESS; + break; case AP_MPMQ_IS_THREADED: *result = AP_MPMQ_STATIC; - return APR_SUCCESS; + break; case AP_MPMQ_IS_FORKED: *result = AP_MPMQ_DYNAMIC; - return APR_SUCCESS; + break; case AP_MPMQ_HARD_LIMIT_DAEMONS: *result = server_limit; - return APR_SUCCESS; + break; case AP_MPMQ_HARD_LIMIT_THREADS: *result = thread_limit; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_THREADS: *result = threads_per_child; - return APR_SUCCESS; + break; case AP_MPMQ_MIN_SPARE_DAEMONS: *result = 0; - return APR_SUCCESS; + break; case AP_MPMQ_MIN_SPARE_THREADS: *result = min_spare_threads; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_SPARE_DAEMONS: *result = 0; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_SPARE_THREADS: *result = max_spare_threads; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_REQUESTS_DAEMON: *result = ap_max_requests_per_child; - return APR_SUCCESS; + break; case AP_MPMQ_MAX_DAEMONS: *result = ap_daemons_limit; - return APR_SUCCESS; + break; case AP_MPMQ_MPM_STATE: *result = mpm_state; - return APR_SUCCESS; + break; case AP_MPMQ_GENERATION: *result = my_generation; - return APR_SUCCESS; + break; + default: + *rv = APR_ENOTIMPL; + break; } - return APR_ENOTIMPL; + return OK; } static apr_status_t worker_note_child_killed(int childnum) diff --git a/server/mpm_common.c b/server/mpm_common.c index 597e388960f..59e175306f0 100644 --- a/server/mpm_common.c +++ b/server/mpm_common.c @@ -88,9 +88,9 @@ AP_IMPLEMENT_HOOK_RUN_ALL(int, drop_privileges, AP_IMPLEMENT_HOOK_RUN_FIRST(int, mpm, (apr_pool_t *pconf, apr_pool_t *plog, server_rec *s), (pconf, plog, s), DECLINED) -AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, mpm_query, - (int query_code, int *result), - (query_code, result), APR_ENOTIMPL) +AP_IMPLEMENT_HOOK_RUN_FIRST(int, mpm_query, + (int query_code, int *result, apr_status_t *_rv), + (query_code, result, _rv), DECLINED) AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, mpm_note_child_killed, (int childnum), (childnum), APR_ENOTIMPL) @@ -405,7 +405,13 @@ AP_DECLARE(int) ap_mpm_run(apr_pool_t *pconf, apr_pool_t *plog, server_rec *serv AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) { - return ap_run_mpm_query(query_code, result); + apr_status_t rv; + + if (ap_run_mpm_query(query_code, result, &rv) == DECLINED) { + rv = APR_EGENERAL; + } + + return rv; } AP_DECLARE(apr_status_t) ap_mpm_note_child_killed(int childnum)