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; > >