]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Don't call into get_worker while holding the timeout_list mutex.
authorPaul Querna <pquerna@apache.org>
Tue, 11 Sep 2007 05:29:54 +0000 (05:29 +0000)
committerPaul Querna <pquerna@apache.org>
Tue, 11 Sep 2007 05:29:54 +0000 (05:29 +0000)
PR: 42031

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

server/mpm/experimental/event/event.c

index abee41be8c2ba88ceab0ec31d103e96d9028470e..290b58fe2303af3a1ee33948a269b7b35c5b47b9 100644 (file)
@@ -1070,14 +1070,20 @@ static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy)
         cs = APR_RING_FIRST(&keepalive_timeout_head);
         timeout_time = time_now + TIMEOUT_FUDGE_FACTOR;
         while (!APR_RING_EMPTY(&keepalive_timeout_head, conn_state_t, timeout_list)
-               && cs->expiration_time < timeout_time
-               && get_worker(&have_idle_worker)) {
+               && cs->expiration_time < timeout_time) {
 
             cs->state = CONN_STATE_LINGER;
 
             APR_RING_REMOVE(cs, timeout_list);
             apr_thread_mutex_unlock(timeout_mutex);
 
+            if (!get_worker(&have_idle_worker)) {
+                apr_thread_mutex_lock(timeout_mutex);
+                APR_RING_INSERT_HEAD(&keepalive_timeout_head, cs,
+                                     conn_state_t, timeout_list);
+                break;
+            }
+
             rc = push2worker(&cs->pfd, event_pollset);
 
             if (rc != APR_SUCCESS) {
@@ -1096,13 +1102,19 @@ static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy)
         /* Step 2: write completion timeouts */
         cs = APR_RING_FIRST(&timeout_head);
         while (!APR_RING_EMPTY(&timeout_head, conn_state_t, timeout_list)
-               && cs->expiration_time < timeout_time
-               && get_worker(&have_idle_worker)) {
+               && cs->expiration_time < timeout_time) {
 
             cs->state = CONN_STATE_LINGER;
             APR_RING_REMOVE(cs, timeout_list);
             apr_thread_mutex_unlock(timeout_mutex);
 
+            if (!get_worker(&have_idle_worker)) {
+                apr_thread_mutex_lock(timeout_mutex);
+                APR_RING_INSERT_HEAD(&timeout_head, cs,
+                                     conn_state_t, timeout_list);
+                break;
+            }
+
             rc = push2worker(&cs->pfd, event_pollset);
             if (rc != APR_SUCCESS) {
                 return NULL;