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;
}
{
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;
}
{
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;
}
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");
}
/*--------------------------------------------------------------------------*/
/* 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);
}
/* 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);
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);
/*
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);
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 */