-*- coding: utf-8 -*-
Changes with Apache 2.4.44
+ *) mod_watchdog: Switch to simpler logic to avoid the thread cleanup running
+ before the thread has started, avoiding mutex operations with undefined
+ behaviour. [Christophe Jaillet]
+
*) mod_http2: The module now handles master/secondary connections and has marked
methods according to use. [Stefan Eissing]
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
[ start all new proposals below, under PATCHES PROPOSED. ]
- *) mod_watchdog: Switch to simpler logic to avoid the thread cleanup running
- before the thread has started, avoiding mutex operations with undefined behaviour
- trunk patch: http://svn.apache.org/r1876511
- 2.4.x patch: svn merge -c 1876511 ^/httpd/httpd/trunk .
- +1: jailletc36 (by inspection), jim, minfrin
PATCHES PROPOSED TO BACKPORT FROM TRUNK:
#include "http_core.h"
#include "util_mutex.h"
+#include "apr_atomic.h"
+
#define AP_WATCHDOG_PGROUP "watchdog"
#define AP_WATCHDOG_PVERSION "parent"
#define AP_WATCHDOG_CVERSION "child"
struct ap_watchdog_t
{
- apr_thread_mutex_t *startup;
+ apr_uint32_t thread_started; /* set to 1 once thread running */
apr_proc_mutex_t *mutex;
const char *name;
watchdog_list_t *callbacks;
apr_status_t rv;
ap_watchdog_t *w = (ap_watchdog_t *)data;
+ /* Do nothing if the thread wasn't started. */
+ if (apr_atomic_read32(&w->thread_started) != 1)
+ return APR_SUCCESS;
+
if (w->is_running) {
watchdog_list_t *wl = w->callbacks;
while (wl) {
w->pool = apr_thread_pool_get(thread);
w->is_running = 1;
- apr_thread_mutex_unlock(w->startup);
+ apr_atomic_set32(&w->thread_started, 1); /* thread started */
+
if (w->mutex) {
while (w->is_running) {
if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpmq_s) != APR_SUCCESS) {
{
apr_status_t rc;
- /* Create thread startup mutex */
- rc = apr_thread_mutex_create(&w->startup, APR_THREAD_MUTEX_UNNESTED, p);
- if (rc != APR_SUCCESS)
- return rc;
+ apr_atomic_set32(&w->thread_started, 0);
if (w->singleton) {
/* Initialize singleton mutex in child */
return rc;
}
- /* This mutex fixes problems with a fast start/fast end, where the pool
- * cleanup was being invoked before the thread completely spawned.
- */
- apr_thread_mutex_lock(w->startup);
- apr_pool_pre_cleanup_register(p, w, wd_worker_cleanup);
-
/* Start the newly created watchdog */
rc = apr_thread_create(&w->thread, NULL, wd_worker, w, p);
- if (rc) {
- apr_pool_cleanup_kill(p, w, wd_worker_cleanup);
+ if (rc == APR_SUCCESS) {
+ apr_pool_pre_cleanup_register(p, w, wd_worker_cleanup);
}
- apr_thread_mutex_lock(w->startup);
- apr_thread_mutex_unlock(w->startup);
- apr_thread_mutex_destroy(w->startup);
-
return rc;
}