Paul has been doing some testing and this patch seems to help (but not solve) the 
reported
problem.  The idea behind the patch is to start as many worker threads as possible on 
the
first pass through the for() loop before starting the listener.  Starting the listener
earlier on a loaded server will drive a lot of additional thread context switches
accepting connections which will just delay the new process getting to steady state.

This patch fixes a couple of problems I noticed with the first patch... with the 
previous
patch, we could get multiple lieteners or in one case we could start the listener w/o
having any worker threads.

Jeff, note that this patch really does not break the graceful restart case since the 
call
to create_listener_thread is still made inside the while (1) loop.

Bill

Index: worker.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/mpm/worker/worker.c,v
retrieving revision 1.117
diff -u -r1.117 worker.c
--- worker.c 18 Apr 2002 17:46:20 -0000 1.117
+++ worker.c 26 Apr 2002 14:50:43 -0000
@@ -948,6 +948,7 @@
     apr_status_t rv;
     int i;
     int threads_created = 0;
+    int listener_started = 0;
     int loops;
     int prev_threads_created;

@@ -999,16 +1000,18 @@
                 clean_child_exit(APEXIT_CHILDFATAL);
             }
             threads_created++;
-            if (threads_created == 1) {
-                /* now that we have a worker thread, it makes sense to create
-                 * a listener thread (we don't want a listener without a worker!)
-                 */
-                create_listener_thread(ts);
-            }
+
+        }
+        /* Start the listener only when there are workers available */
+        if (!listener_started && threads_created) {
+            create_listener_thread(ts);
+            listener_started = 1;
         }
+
         if (start_thread_may_exit || threads_created == ap_threads_per_child) {
             break;
         }
+
         /* wait for previous generation to clean up an entry */
         apr_sleep(1 * APR_USEC_PER_SEC);
         ++loops;


> Would someone care to see if this fixes the worker MPM performance problem reported
> earlier on the list (request-per-second dropping when clients exceeded 
>threadsperchild)?
> This patch defers starting the listener untill -all- the workers have started.
>
> Bill
>
> Index: worker.c
> ===================================================================
> RCS file: /home/cvs/httpd-2.0/server/mpm/worker/worker.c,v
> retrieving revision 1.117
> diff -u -r1.117 worker.c
> --- worker.c 18 Apr 2002 17:46:20 -0000 1.117
> +++ worker.c 25 Apr 2002 15:24:51 -0000
> @@ -999,16 +999,15 @@
>                  clean_child_exit(APEXIT_CHILDFATAL);
>              }
>              threads_created++;
> -            if (threads_created == 1) {
> -                /* now that we have a worker thread, it makes sense to create
> -                 * a listener thread (we don't want a listener without a worker!)
> -                 */
> -                create_listener_thread(ts);
> -            }
> +
>          }
>          if (start_thread_may_exit || threads_created == ap_threads_per_child) {
>              break;
>          }
> +
> +        /* All the workers have started. Now start the listener thread */
> +        create_listener_thread(ts);
> +
>          /* wait for previous generation to clean up an entry */
>          apr_sleep(1 * APR_USEC_PER_SEC);
>          ++loops;
>
>

Reply via email to