summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--modules/core/mod_watchdog.c21
-rw-r--r--server/mpm/prefork/prefork.c19
2 files changed, 29 insertions, 11 deletions
diff --git a/modules/core/mod_watchdog.c b/modules/core/mod_watchdog.c
index 94a72c2416..5da2a0c681 100644
--- a/modules/core/mod_watchdog.c
+++ b/modules/core/mod_watchdog.c
@@ -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);
diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c
index 71532d611c..e26ee4f7ef 100644
--- a/server/mpm/prefork/prefork.c
+++ b/server/mpm/prefork/prefork.c
@@ -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 */