* core/mpm: add hook 'child_stopping` that gets called when the MPM is
stopping a child process. The additional `graceful` parameter allows
registered hooks to free resources early during a graceful shutdown.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1891919 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/changes-entries/core_child_stopping.txt b/changes-entries/core_child_stopping.txt
new file mode 100644
index 0000000..c85230e
--- /dev/null
+++ b/changes-entries/core_child_stopping.txt
@@ -0,0 +1,4 @@
+ * core/mpm: add hook 'child_stopping` that gets called when the MPM is
+ stopping a child process. The additional `graceful` parameter allows
+ registered hooks to free resources early during a graceful shutdown.
+ [Yann Ylavic, Stefan Eissing]
diff --git a/include/ap_mmn.h b/include/ap_mmn.h
index 57166ba..126c7e6 100644
--- a/include/ap_mmn.h
+++ b/include/ap_mmn.h
@@ -677,6 +677,8 @@
* ap_bucket_wc_create() to util_filter.h
* 20210531.2 (2.5.1-dev) Add ap_proxy_get_worker_ex() and
* ap_proxy_define_worker_ex() to mod_proxy.h
+ * 20210531.3 (2.5.1-dev) Add hook child_stopping to get informed that a child
+ * is being shut down.
*/
#define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
diff --git a/include/mpm_common.h b/include/mpm_common.h
index a8e7b03..007a24a 100644
--- a/include/mpm_common.h
+++ b/include/mpm_common.h
@@ -511,6 +511,15 @@
AP_DECLARE_HOOK(void, resume_connection,
(conn_rec *c, request_rec *r))
+/**
+ * Notification that the child is stopping. If graceful, ongoing
+ * requests will be served.
+ * @param pchild The child pool
+ * @param graceful != 0 iff this is a graceful shutdown.
+ */
+AP_DECLARE_HOOK(void, child_stopping,
+ (apr_pool_t *pchild, int graceful))
+
/* mutex type string for accept mutex, if any; MPMs should use the
* same mutex type for ease of configuration
*/
diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c
index 24a90c8..1a27a8f 100644
--- a/server/mpm/event/event.c
+++ b/server/mpm/event/event.c
@@ -659,6 +659,8 @@
ap_queue_interrupt_all(worker_queue);
close_worker_sockets(); /* forcefully kill all current connections */
}
+
+ ap_run_child_stopping(pchild, mode == ST_GRACEFUL);
}
static int event_query(int query_code, int *result, apr_status_t *rv)
@@ -758,6 +760,10 @@
static void clean_child_exit(int code)
{
retained->mpm->mpm_state = AP_MPMQ_STOPPING;
+ if (terminate_mode == ST_INIT) {
+ ap_run_child_stopping(pchild, 0);
+ }
+
if (pchild) {
apr_pool_destroy(pchild);
}
diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c
index 4cef7b6..447b901 100644
--- a/server/mpm/prefork/prefork.c
+++ b/server/mpm/prefork/prefork.c
@@ -219,11 +219,14 @@
static void clean_child_exit(int code) __attribute__ ((noreturn));
static void clean_child_exit(int code)
{
- retained->mpm->mpm_state = AP_MPMQ_STOPPING;
-
apr_signal(SIGHUP, SIG_IGN);
apr_signal(SIGTERM, SIG_IGN);
+ retained->mpm->mpm_state = AP_MPMQ_STOPPING;
+ if (code == 0) {
+ ap_run_child_stopping(pchild, 0);
+ }
+
if (pchild) {
apr_pool_destroy(pchild);
/*
diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c
index 94c47ef..cf18372 100644
--- a/server/mpm/worker/worker.c
+++ b/server/mpm/worker/worker.c
@@ -325,6 +325,8 @@
ap_queue_interrupt_all(worker_queue);
close_worker_sockets(); /* forcefully kill all current connections */
}
+
+ ap_run_child_stopping(pchild, mode == ST_GRACEFUL);
}
static int worker_query(int query_code, int *result, apr_status_t *rv)
@@ -433,6 +435,10 @@
static void clean_child_exit(int code)
{
retained->mpm->mpm_state = AP_MPMQ_STOPPING;
+ if (terminate_mode == ST_INIT) {
+ ap_run_child_stopping(pchild, 0);
+ }
+
if (pchild) {
apr_pool_destroy(pchild);
}
diff --git a/server/mpm_common.c b/server/mpm_common.c
index d5a27fa..4b8c41e 100644
--- a/server/mpm_common.c
+++ b/server/mpm_common.c
@@ -77,7 +77,8 @@
APR_HOOK_LINK(output_pending) \
APR_HOOK_LINK(input_pending) \
APR_HOOK_LINK(suspend_connection) \
- APR_HOOK_LINK(resume_connection)
+ APR_HOOK_LINK(resume_connection) \
+ APR_HOOK_LINK(child_stopping)
#if AP_ENABLE_EXCEPTION_HOOK
APR_HOOK_STRUCT(
@@ -136,6 +137,9 @@
AP_IMPLEMENT_HOOK_VOID(resume_connection,
(conn_rec *c, request_rec *r),
(c, r))
+AP_IMPLEMENT_HOOK_VOID(child_stopping,
+ (apr_pool_t *pchild, int graceful),
+ (pchild, graceful))
/* hooks with no args are implemented last, after disabling APR hook probes */
#if defined(APR_HOOK_PROBES_ENABLED)