diff options
author | Jeff Trawick <trawick@apache.org> | 2011-11-10 17:46:57 +0000 |
---|---|---|
committer | Jeff Trawick <trawick@apache.org> | 2011-11-10 17:46:57 +0000 |
commit | 5405226ae2190c03dc84c816a709d3b8187c7218 (patch) | |
tree | 81f6f94dcb4de9fc910e8d3bc694ed9d5c96e1e0 | |
parent | e66f481ac366291f70cea605b65fb937ea3899cc (diff) | |
download | httpd-5405226ae2190c03dc84c816a709d3b8187c7218.tar.gz |
end-generation hook: Fix false notification of end-of-generation for
temporary intervals with no active MPM children.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1200449 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | include/mpm_common.h | 5 | ||||
-rw-r--r-- | server/core.c | 2 | ||||
-rw-r--r-- | server/mpm_common.c | 53 |
4 files changed, 56 insertions, 7 deletions
@@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.3.16 + *) end-generation hook: Fix false notification of end-of-generation for + temporary intervals with no active MPM children. [Jeff Trawick] + *) mod_ssl: Add support for RFC 5077 TLS Session tickets. [Paul Querna] diff --git a/include/mpm_common.h b/include/mpm_common.h index f342c290ab..e6700264ec 100644 --- a/include/mpm_common.h +++ b/include/mpm_common.h @@ -137,6 +137,11 @@ void ap_register_extra_mpm_process(pid_t pid, ap_generation_t gen); int ap_unregister_extra_mpm_process(pid_t pid, ap_generation_t *old_gen); /** + * Pool cleanup for end-generation hook implementation + */ +apr_status_t ap_mpm_end_gen_helper(void *unused); + +/** * Safely signal an MPM child process, if the process is in the * current process group. Otherwise fail. * @param pid the process id of a child process to signal diff --git a/server/core.c b/server/core.c index dc06843269..751c32219b 100644 --- a/server/core.c +++ b/server/core.c @@ -4389,6 +4389,8 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte "or other system security module is loaded."); return !OK; } + apr_pool_cleanup_register(pconf, NULL, ap_mpm_end_gen_helper, + apr_pool_cleanup_null); return OK; } diff --git a/server/mpm_common.c b/server/mpm_common.c index d189920072..3663167fc3 100644 --- a/server/mpm_common.c +++ b/server/mpm_common.c @@ -131,6 +131,7 @@ typedef struct mpm_gen_info_t { APR_RING_ENTRY(mpm_gen_info_t) link; int gen; /* which gen? */ int active; /* number of active processes */ + int done; /* gen finished? (whether or not active processes) */ } mpm_gen_info_t; APR_RING_HEAD(mpm_gen_info_head_t, mpm_gen_info_t); @@ -413,9 +414,50 @@ AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) return rv; } +static void end_gen(mpm_gen_info_t *gi) +{ + ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf, + "end of generation %d", gi->gen); + ap_run_end_generation(ap_server_conf, gi->gen); + APR_RING_REMOVE(gi, link); + APR_RING_INSERT_HEAD(unused_geninfo, gi, mpm_gen_info_t, link); +} + +apr_status_t ap_mpm_end_gen_helper(void *unused) /* cleanup on pconf */ +{ + int gen = ap_config_generation - 1; /* differs from MPM generation */ + mpm_gen_info_t *cur; + + if (geninfo == NULL) { + /* initial pconf teardown, MPM hasn't run */ + return APR_SUCCESS; + } + + cur = APR_RING_FIRST(geninfo); + while (cur != APR_RING_SENTINEL(geninfo, mpm_gen_info_t, link) && + cur->gen != gen) { + cur = APR_RING_NEXT(cur, link); + } + + if (cur == APR_RING_SENTINEL(geninfo, mpm_gen_info_t, link)) { + /* last child of generation already exited */ + ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf, + "no record of generation %d", gen); + } + else { + cur->done = 1; + if (cur->active == 0) { + end_gen(cur); + } + } + + return APR_SUCCESS; +} + /* core's child-status hook * tracks number of remaining children per generation and - * runs the end-generation hook when a generation finishes + * runs the end-generation hook when the last child of + * a generation exits */ void ap_core_child_status(server_rec *s, pid_t pid, ap_generation_t gen, int slot, @@ -446,6 +488,7 @@ void ap_core_child_status(server_rec *s, pid_t pid, if (!APR_RING_EMPTY(unused_geninfo, mpm_gen_info_t, link)) { cur = APR_RING_FIRST(unused_geninfo); APR_RING_REMOVE(cur, link); + cur->active = cur->done = 0; } else { cur = apr_pcalloc(s->process->pool, sizeof *cur); @@ -466,12 +509,8 @@ void ap_core_child_status(server_rec *s, pid_t pid, } else { --cur->active; - if (!cur->active) { - ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf, - "end of generation %d", gen); - ap_run_end_generation(ap_server_conf, gen); - APR_RING_REMOVE(cur, link); - APR_RING_INSERT_HEAD(unused_geninfo, cur, mpm_gen_info_t, link); + if (!cur->active && cur->done) { /* no children, server has stopped/restarted */ + end_gen(cur); } } break; |