]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Tweak worker thread accounting routines to eliminate
authorGeoffrey Young <geoff@apache.org>
Wed, 24 Mar 2004 20:28:49 +0000 (20:28 +0000)
committerGeoffrey Young <geoff@apache.org>
Wed, 24 Mar 2004 20:28:49 +0000 (20:28 +0000)
server hang when number of Listen directives in httpd.conf
is greater than or equal to the setting of ThreadsPerChild.
Reviewed by:  stoddard, trawick, geoff

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

CHANGES
server/mpm/winnt/child.c

diff --git a/CHANGES b/CHANGES
index 04eaf929457093ad3fef08aacaa8ce547a954e02..eda5c594bcb37ae62ad62417b0a52b732d9eb37c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,11 @@ Changes with Apache 2.0.50
 
 Changes with Apache 2.0.49
 
+  *) 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]
+
   *) SECURITY: CAN-2004-0174 (cve.mitre.org)
      Fix starvation issue on listening sockets where a short-lived
      connection on a rarely-accessed listening socket will cause a
index 8109bb33938b2d0ea8f5ee0857b9faa68ba8eac1..7a88b1c89c606a3356632120fdb270c84a10a6b3 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) {
@@ -766,6 +768,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);
@@ -774,6 +777,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,