summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Trawick <trawick@apache.org>2010-09-24 13:25:25 +0200
committerJeff Trawick <trawick@apache.org>2010-09-24 13:25:25 +0200
commite5ab365322cd6ef16b63e26288f170aebbc31132 (patch)
treee6e8f8ccd4c4c4c570f0d6b2307c91ee365bf272
parentAdded util_regex.c to NetWare makefile. (diff)
downloadapache2-e5ab365322cd6ef16b63e26288f170aebbc31132.tar.xz
apache2-e5ab365322cd6ef16b63e26288f170aebbc31132.zip
Fix crash accessing pollset on worker thread when child process is exiting.
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
-rw-r--r--CHANGES3
-rw-r--r--server/mpm/event/event.c39
2 files changed, 24 insertions, 18 deletions
diff --git a/CHANGES b/CHANGES
index 2c64dcb58f..647727f284 100644
--- 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
diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c
index 371eb6620d..452a67b773 100644
--- a/server/mpm/event/event.c
+++ b/server/mpm/event/event.c
@@ -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 *));