]> granicus.if.org Git - apache/commitdiff
Win32: Tweak worker thread accounting to fix hang when number of Listen directives...
authorBill Stoddard <stoddard@apache.org>
Wed, 10 Mar 2004 15:05:52 +0000 (15:05 +0000)
committerBill Stoddard <stoddard@apache.org>
Wed, 10 Mar 2004 15:05:52 +0000 (15:05 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@102922 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
server/mpm/winnt/child.c

diff --git a/CHANGES b/CHANGES
index adac282caf09cf791a8d150c36bea710f18477a2..78b03708203102aaebf6a4ee3251e3f720099c4c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
 Changes with Apache 2.1.0-dev
 
   [Remove entries to the current 2.0 section below, when backported]
+  *) Win32: Tweak worker thread accounting routines to eliminate
+     server hang when number of Listen directives in httpd.conf
+     is greater than or equal to the setting of ThreadsPerChild.
+     [Bill Stoddard]
 
   *) mod_rewrite: Support for recognizing SSL variables in RewriteCond
      using the new "SSL:" format.  [Joe Orton, Madhusudan Mathihalli]
index b6f9e5f96a5953c3e6cd35839ce4a3dde0848d27..76ab5b45c44160c33c9f758b7a19566d182a223f 100644 (file)
@@ -63,6 +63,7 @@ static apr_thread_mutex_t  *qlock;
 static PCOMP_CONTEXT qhead = NULL;
 static PCOMP_CONTEXT qtail = NULL;
 static int num_completion_contexts = 0;
+static int max_num_completion_contexts = 0;
 static HANDLE ThreadDispatchIOCP = NULL;
 static HANDLE qwait_event = NULL;
 
@@ -111,11 +112,12 @@ AP_DECLARE(PCOMP_CONTEXT) mpm_get_completion_context(void)
         apr_thread_mutex_unlock(qlock);
   
         if (!context) {
-            /* We failed to grab a context off the queue, consider allocating a
-             * new one out of the child pool. There may be up to ap_threads_per_child
-             * contexts in the system at once.
+            /* We failed to grab a context off the queue, consider allocating
+             * a new one out of the child pool. There may be up to 
+             * (ap_threads_per_child + num_listeners) contexts in the system 
+             * at once.
              */
-            if (num_completion_contexts >= ap_threads_per_child) {
+            if (num_completion_contexts >= max_num_completion_contexts) {
                 /* All workers are busy, need to wait for one */
                 static int reported = 0;
                 if (!reported) {
@@ -811,6 +813,7 @@ static void cleanup_thread(HANDLE *handles, int *thread_cnt, int thread_to_clean
 static void create_listener_thread()
 {
     int tid;
+    int num_listeners = 0;
     if (!use_acceptex) {
         _beginthreadex(NULL, 0, (LPTHREAD_START_ROUTINE) win9x_accept,
                        NULL, 0, &tid);
@@ -819,6 +822,20 @@ static void create_listener_thread()
          * XXX: Why would we have a NULL sd in our listeners?
          */
         ap_listen_rec *lr;
+
+        /* Number of completion_contexts allowed in the system is
+         * (ap_threads_per_child + num_listeners). We need the additional
+         * completion contexts to prevent server hangs when ThreadsPerChild
+         * is configured to something less than or equal to the number
+         * of listeners. This is not a usual case, but people have 
+         * encountered it.
+         * */
+        for (lr = ap_listeners; lr ; lr = lr->next) {
+            num_listeners++;
+        }
+        max_num_completion_contexts = ap_threads_per_child + num_listeners;
+
+        /* Now start a thread per listener */
         for (lr = ap_listeners; lr; lr = lr->next) {
             if (lr->sd != NULL) {
                 _beginthreadex(NULL, 1000, (LPTHREAD_START_ROUTINE) winnt_accept,