]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
*) mod_watchdog: add assertions to cleanup code
authorStefan Eissing <icing@apache.org>
Fri, 25 Feb 2022 13:18:51 +0000 (13:18 +0000)
committerStefan Eissing <icing@apache.org>
Fri, 25 Feb 2022 13:18:51 +0000 (13:18 +0000)
  *) core/mpm_preform: do not invoke the fancy new child_stopping/stopped
     hooks when invoked from a signal handler. This is a stopgap to some
     strange behaviour in need of some deeper insight.

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

modules/core/mod_watchdog.c
server/mpm/prefork/prefork.c

index 94a72c24165b3a97f1002df4c8763127eb7321a6..5da2a0c68104d5dd76532d7db26ab3b6fc10a068 100644 (file)
@@ -78,11 +78,13 @@ static apr_status_t wd_worker_cleanup(void *data)
     ap_watchdog_t *w = (ap_watchdog_t *)data;
 
     /* Do nothing if the thread wasn't started or has terminated. */
-    if (apr_atomic_read32(&w->thread_started) != 1)
+    if (!w->thread || apr_atomic_read32(&w->thread_started) != 1)
         return APR_SUCCESS;
 
+    AP_DEBUG_ASSERT(w->thread);
     apr_atomic_set32(&w->is_running, 0);
     apr_thread_join(&rv, w->thread);
+    w->thread = NULL;
     return rv;
 }
 
@@ -557,6 +559,8 @@ static void wd_child_stopping(apr_pool_t *pool, int graceful)
 {
     const apr_array_header_t *wl;
 
+    ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, wd_server_conf->s,
+                 "child stopping graceful=%d", graceful);
     if (!wd_server_conf->child_workers) {
         return;
     }
@@ -585,6 +589,8 @@ static void wd_child_stopped(apr_pool_t *pool, int graceful)
 {
     const apr_array_header_t *wl;
 
+    ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, wd_server_conf->s,
+                 "child stopped, joining watchdog threads");
     if (!wd_server_conf->child_workers) {
         return;
     }
@@ -598,9 +604,14 @@ static void wd_child_stopped(apr_pool_t *pool, int graceful)
             ap_watchdog_t *w = ap_lookup_provider(AP_WATCHDOG_PGROUP,
                                                   wn[i].provider_name,
                                                   AP_WATCHDOG_CVERSION);
+            ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, wd_server_conf->s,
+                         "%sWatchdog (%s) stopping now",
+                         w->singleton ? "Singleton " : "", w->name);
             wd_worker_cleanup(w);
         }
     }
+    ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, wd_server_conf->s,
+                 "child stopped, watchdogs stopped");
 }
 
 /*--------------------------------------------------------------------------*/
@@ -689,10 +700,10 @@ static void wd_register_hooks(apr_pool_t *p)
 
     /* Child has stopped hook
      */
-    ap_hook_child_stopping(wd_child_stopped,
-                           NULL,
-                           NULL,
-                           APR_HOOK_MIDDLE);
+    ap_hook_child_stopped(wd_child_stopped,
+                          NULL,
+                          NULL,
+                          APR_HOOK_MIDDLE);
 
     APR_REGISTER_OPTIONAL_FN(ap_watchdog_get_instance);
     APR_REGISTER_OPTIONAL_FN(ap_watchdog_register_callback);
index 71532d611cc0f1015dfab7fbd04943f6583afc87..e26ee4f7efe127291edc32b75d70a548d7844f7a 100644 (file)
@@ -218,8 +218,8 @@ static void prefork_note_child_started(int slot, pid_t pid)
 }
 
 /* a clean exit from a child with proper cleanup */
-static void clean_child_exit(int code) __attribute__ ((noreturn));
-static void clean_child_exit(int code)
+static void clean_child_exit_ex(int code, int from_signal) __attribute__ ((noreturn));
+static void clean_child_exit_ex(int code, int from_signal)
 {
     apr_signal(SIGHUP, SIG_IGN);
     apr_signal(SIGTERM, SIG_IGN);
@@ -227,9 +227,9 @@ static void clean_child_exit(int code)
     retained->mpm->mpm_state = AP_MPMQ_STOPPING;
 
     if (pchild) {
-        if (code == 0) {
-            ap_run_child_stopping(pchild, 0);
-            ap_run_child_stopped(pchild, 0);
+        if (!code && !from_signal) {
+            ap_run_child_stopping(pchild, !retained->mpm->is_ungraceful);
+            ap_run_child_stopped(pchild, !retained->mpm->is_ungraceful);
         }
         apr_pool_destroy(pchild);
         /*
@@ -248,6 +248,13 @@ static void clean_child_exit(int code)
     exit(code);
 }
 
+/* a clean exit from a child with proper cleanup */
+static void clean_child_exit(int code) __attribute__ ((noreturn));
+static void clean_child_exit(int code)
+{
+    clean_child_exit_ex(code, 0);
+}
+
 static apr_status_t accept_mutex_on(void)
 {
     apr_status_t rv = apr_proc_mutex_lock(my_bucket->mutex);
@@ -364,7 +371,7 @@ static const char *prefork_get_name(void)
 
 static void just_die(int sig)
 {
-    clean_child_exit(0);
+    clean_child_exit_ex(0, 1);
 }
 
 /* volatile because it's updated from a signal handler */