]> granicus.if.org Git - apache/commitdiff
Fix crash accessing pollset on worker thread when child process is exiting.
authorJeff Trawick <trawick@apache.org>
Fri, 24 Sep 2010 11:25:25 +0000 (11:25 +0000)
committerJeff Trawick <trawick@apache.org>
Fri, 24 Sep 2010 11:25:25 +0000 (11:25 +0000)
The timeout mutex and pollset were allocated from the listener thread
pool.  During child process shutdown, the listener thread exits first
while any outstanding requests finish.  These objects need to be allocated
from pchild since the lifetime extends until the last worker thread has
finished.

Switch to pchild, and move init of these objects to the same place as
other thread-independent objects.

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

CHANGES
server/mpm/event/event.c

diff --git a/CHANGES b/CHANGES
index 2c64dcb58fefc3225361d901b8335aea5257284c..647727f284ad2e733b13a3c9863dafb0a99a6c15 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,9 @@
 
 Changes with Apache 2.3.9
 
+  *) Event MPM: Fix crash accessing pollset on worker thread when child
+     process is exiting.  [Jeff Trawick]
+
   *) core: For process invocation (cgi, fcgid, piped loggers and so forth)
      pass the system library path (LD_LIBRARY_PATH or platform-specific
      variables) along with the system PATH, by default.  Both should be 
index 371eb6620d24abba70164b9300f001e43fe6a494..452a67b773ac907af9cba2dc93c3ca988c5522a7 100644 (file)
@@ -826,30 +826,12 @@ static apr_status_t init_pollset(apr_pool_t *p)
 #if HAVE_SERF
     s_baton_t *baton = NULL;
 #endif
-    apr_status_t rv;
     ap_listen_rec *lr;
     listener_poll_type *pt;
 
-    rv = apr_thread_mutex_create(&timeout_mutex, APR_THREAD_MUTEX_DEFAULT, p);
-    if (rv != APR_SUCCESS) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
-                     "creation of the timeout mutex failed.");
-        return rv;
-    }
-
     APR_RING_INIT(&timeout_head, conn_state_t, timeout_list);
     APR_RING_INIT(&keepalive_timeout_head, conn_state_t, timeout_list);
 
-    /* Create the main pollset */
-    rv = apr_pollset_create(&event_pollset,
-                            threads_per_child,
-                            p, APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY);
-    if (rv != APR_SUCCESS) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
-                     "apr_pollset_create with Thread Safety failed.");
-        return rv;
-    }
-
     for (lr = ap_listeners; lr != NULL; lr = lr->next) {
         apr_pollfd_t *pfd = apr_palloc(p, sizeof(*pfd));
         pt = apr_pcalloc(p, sizeof(*pt));
@@ -1507,6 +1489,27 @@ static void *APR_THREAD_FUNC start_threads(apr_thread_t * thd, void *dummy)
         clean_child_exit(APEXIT_CHILDFATAL);
     }
 
+    /* Create the timeout mutex and main pollset before the listener
+     * thread starts.
+     */
+    rv = apr_thread_mutex_create(&timeout_mutex, APR_THREAD_MUTEX_DEFAULT,
+                                 pchild);
+    if (rv != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
+                     "creation of the timeout mutex failed.");
+        clean_child_exit(APEXIT_CHILDFATAL);
+    }
+
+    /* Create the main pollset */
+    rv = apr_pollset_create(&event_pollset,
+                            threads_per_child,
+                            pchild, APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY);
+    if (rv != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
+                     "apr_pollset_create with Thread Safety failed.");
+        clean_child_exit(APEXIT_CHILDFATAL);
+    }
+
     worker_sockets = apr_pcalloc(pchild, threads_per_child
                                  * sizeof(apr_socket_t *));