mpm_event: make sure wakeup_listener() does its minimal job.
Even if the listener thread is not created yet (i.e. about to be), we must
still tell it to leave, and terminate the worker queue in any case.
@@ -570,23 +570,25 @@ static void close_worker_sockets(void)
static void wakeup_listener(void)
{
listener_may_exit = 1;
- if (!listener_os_thread) {
- /* XXX there is an obscure path that this doesn't handle perfectly:
- * right after listener thread is created but before
- * listener_os_thread is set, the first worker thread hits an
- * error and starts graceful termination
- */
- return;
- }
/* Unblock the listener if it's poll()ing */
- if (listener_is_wakeable) {
+ if (event_pollset && listener_is_wakeable) {
apr_pollset_wakeup(event_pollset);
}
/* unblock the listener if it's waiting for a worker */
+ if (worker_queue_info) {
ap_queue_info_term(worker_queue_info);
+ }
+ if (!listener_os_thread) {
+ /* XXX there is an obscure path that this doesn't handle perfectly:
+ * right after listener thread is created but before
+ * listener_os_thread is set, the first worker thread hits an
+ * error and starts graceful termination
+ */
+ return;
+ }
/*
* we should just be able to "kill(ap_my_pid, LISTENER_SIGNAL)" on all
* platforms and wake up the listener thread since it is the only thread
@@ -607,7 +609,7 @@ static int terminate_mode = ST_INIT;
static void signal_threads(int mode)
{
- if (terminate_mode == mode) {
+ if (terminate_mode >= mode) {
return;
}
terminate_mode = mode;
@@ -3608,6 +3610,10 @@ static int event_pre_config(apr_pool_t * pconf, apr_pool_t * plog,
had_healthy_child = 0;
ap_extended_status = 0;
+ event_pollset = NULL;
+ worker_queue_info = NULL;
+ listener_os_thread = NULL;
+
return OK;
}
