Commit 0539bb45 authored by Brian Pane's avatar Brian Pane
Browse files

Fix for the worker deadlock problem


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@95270 13f79535-47bb-0310-9956-ffa450edef68
parent 4da373ce
Loading
Loading
Loading
Loading
+2 −0
Changes for CHANGES: 2 added lines, 0 removed lines.
Original line number Diff line number Diff line
Changes with Apache 2.0.37
  *) Fix the worker MPM deadlock problem  [Brian Pane]
  *) Modify the module documentation to allow for translations.
     [Yoshiki Hayashi, Joshua Slive]
+15 −2
Changes for server/mpm/worker/worker.c: 15 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -689,6 +689,7 @@ static void *listener_thread(apr_thread_t *thd, void * dummy)
    apr_pollfd_t *pollset;
    apr_status_t rv;
    ap_listen_rec *lr, *last_lr = ap_listeners;
    int have_idle_worker = 0;

    free(ti);

@@ -711,6 +712,7 @@ static void *listener_thread(apr_thread_t *thd, void * dummy)
        }
        if (listener_may_exit) break;

        if (!have_idle_worker) {
            rv = ap_queue_info_wait_for_idler(worker_queue_info,
                                              &recycled_pool);
            if (APR_STATUS_IS_EOF(rv)) {
@@ -718,11 +720,14 @@ static void *listener_thread(apr_thread_t *thd, void * dummy)
            }
            else if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
                         "apr_queue_info_wait failed. Attempting to shutdown "
                         "process gracefully.");
                             "apr_queue_info_wait failed. Attempting to "
                             " shutdown process gracefully.");
                signal_threads(ST_GRACEFUL);
                break;
            }
            have_idle_worker = 1;
        }
            
        /* We've already decremented the idle worker count inside
         * ap_queue_info_wait_for_idler. */

@@ -833,6 +838,9 @@ static void *listener_thread(apr_thread_t *thd, void * dummy)
                    ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
                                 "ap_queue_push failed");
                }
                else {
                    have_idle_worker = 0;
                }
            }
        }
        else {
@@ -875,6 +883,7 @@ static void * APR_THREAD_FUNC worker_thread(apr_thread_t *thd, void * dummy)
    apr_pool_t *last_ptrans = NULL;
    apr_pool_t *ptrans;                /* Pool for per-transaction stuff */
    apr_status_t rv;
    int is_idle = 0;

    free(ti);

@@ -883,6 +892,7 @@ static void * APR_THREAD_FUNC worker_thread(apr_thread_t *thd, void * dummy)
    bucket_alloc = apr_bucket_alloc_create(apr_thread_pool_get(thd));

    while (!workers_may_exit) {
        if (!is_idle) {
            rv = ap_queue_info_set_idle(worker_queue_info, last_ptrans);
            last_ptrans = NULL;
            if (rv != APR_SUCCESS) {
@@ -892,6 +902,8 @@ static void * APR_THREAD_FUNC worker_thread(apr_thread_t *thd, void * dummy)
                signal_threads(ST_GRACEFUL);
                break;
            }
            is_idle = 1;
        }

        ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_READY, NULL);
worker_pop:
@@ -928,6 +940,7 @@ worker_pop:
            }
            continue;
        }
        is_idle = 0;
        worker_sockets[thread_slot] = csd;
        process_socket(ptrans, csd, process_slot, thread_slot, bucket_alloc);
        worker_sockets[thread_slot] = NULL;