Main Page | Modules | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages | Examples

leader.c

Go to the documentation of this file.
00001 /* Copyright 2002-2005 The Apache Software Foundation or its licensors, as
00002  * applicable.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "apr.h"
00018 #include "apr_portable.h"
00019 #include "apr_strings.h"
00020 #include "apr_file_io.h"
00021 #include "apr_thread_proc.h"
00022 #include "apr_signal.h"
00023 #include "apr_thread_cond.h"
00024 #include "apr_thread_mutex.h"
00025 #include "apr_proc_mutex.h"
00026 #define APR_WANT_STRFUNC
00027 #include "apr_want.h"
00028 
00029 #if APR_HAVE_UNISTD_H
00030 #include <unistd.h>
00031 #endif
00032 #if APR_HAVE_SYS_SOCKET_H
00033 #include <sys/socket.h>
00034 #endif
00035 #if APR_HAVE_SYS_WAIT_H
00036 #include <sys/wait.h> 
00037 #endif
00038 #ifdef HAVE_SYS_PROCESSOR_H
00039 #include <sys/processor.h> /* for bindprocessor() */
00040 #endif
00041 
00042 #if !APR_HAS_THREADS
00043 #error The Leader/Follower MPM requires APR threads, but they are unavailable.
00044 #endif
00045 
00046 #define CORE_PRIVATE 
00047  
00048 #include "ap_config.h"
00049 #include "httpd.h" 
00050 #include "http_main.h" 
00051 #include "http_log.h" 
00052 #include "http_config.h"        /* for read_config */ 
00053 #include "http_core.h"          /* for get_remote_host */ 
00054 #include "http_connection.h"
00055 #include "ap_mpm.h"
00056 #include "mpm_common.h"
00057 #include "ap_listen.h"
00058 #include "scoreboard.h" 
00059 #include "mpm_default.h"
00060 #include "apr_poll.h"
00061 
00062 #include <signal.h>
00063 #include <limits.h>             /* for INT_MAX */
00064 
00065 #include "apr_atomic.h"
00066 
00067 /* Limit on the total --- clients will be locked out if more servers than
00068  * this are needed.  It is intended solely to keep the server from crashing
00069  * when things get out of hand.
00070  *
00071  * We keep a hard maximum number of servers, for two reasons --- first off,
00072  * in case something goes seriously wrong, we want to stop the fork bomb
00073  * short of actually crashing the machine we're running on by filling some
00074  * kernel table.  Secondly, it keeps the size of the scoreboard file small
00075  * enough that we can read the whole thing without worrying too much about
00076  * the overhead.
00077  */
00078 #ifndef DEFAULT_SERVER_LIMIT
00079 #define DEFAULT_SERVER_LIMIT 16
00080 #endif
00081 
00082 /* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT.  We want
00083  * some sort of compile-time limit to help catch typos.
00084  */
00085 #ifndef MAX_SERVER_LIMIT
00086 #define MAX_SERVER_LIMIT 20000
00087 #endif
00088 
00089 /* Limit on the threads per process.  Clients will be locked out if more than
00090  * this  * server_limit are needed.
00091  *
00092  * We keep this for one reason it keeps the size of the scoreboard file small
00093  * enough that we can read the whole thing without worrying too much about
00094  * the overhead.
00095  */
00096 #ifndef DEFAULT_THREAD_LIMIT
00097 #define DEFAULT_THREAD_LIMIT 64 
00098 #endif
00099 
00100 /* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT.  We want
00101  * some sort of compile-time limit to help catch typos.
00102  */
00103 #ifndef MAX_THREAD_LIMIT
00104 #define MAX_THREAD_LIMIT 20000
00105 #endif
00106 
00107 /*
00108  * Actual definitions of config globals
00109  */
00110 
00111 int ap_threads_per_child = 0;         /* Worker threads per child */
00112 static int ap_daemons_to_start = 0;
00113 static int min_spare_threads = 0;
00114 static int max_spare_threads = 0;
00115 static int ap_daemons_limit = 0;
00116 static int server_limit = DEFAULT_SERVER_LIMIT;
00117 static int first_server_limit;
00118 static int thread_limit = DEFAULT_THREAD_LIMIT;
00119 static int first_thread_limit;
00120 static int changed_limit_at_restart;
00121 static int dying = 0;
00122 static int workers_may_exit = 0;
00123 static int start_thread_may_exit = 0;
00124 static int requests_this_child;
00125 static int num_listensocks = 0;
00126 static int resource_shortage = 0;
00127 static int mpm_state = AP_MPMQ_STARTING;
00128 
00129 typedef struct worker_wakeup_info worker_wakeup_info;
00130 
00131 /* The structure used to pass unique initialization info to each thread */
00132 typedef struct {
00133     int pid;
00134     int tid;
00135     int sd;
00136 } proc_info;
00137 
00138 
00139 /* Structure used to pass information to the thread responsible for 
00140  * creating the rest of the threads.
00141  */
00142 typedef struct {
00143     apr_thread_t **threads;
00144     int child_num_arg;
00145     apr_threadattr_t *threadattr;
00146 } thread_starter;
00147 
00148 #define ID_FROM_CHILD_THREAD(c, t)    ((c * thread_limit) + t)
00149 
00150 /*
00151  * The max child slot ever assigned, preserved across restarts.  Necessary
00152  * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts.  We 
00153  * use this value to optimize routines that have to scan the entire 
00154  * scoreboard.
00155  */
00156 int ap_max_daemons_limit = -1;
00157 
00158 static ap_pod_t *pod;
00159 
00160 /* *Non*-shared http_main globals... */
00161 
00162 server_rec *ap_server_conf;
00163 
00164 /* This MPM respects a couple of runtime flags that can aid in debugging.
00165  *  Setting the -DNO_DETACH flag will prevent the root process from
00166  *  detaching from its controlling terminal. Additionally, setting
00167  * the -DONE_PROCESS flag (which implies -DNO_DETACH) will get you the
00168  * child_main loop running in the process which originally started up.
00169  * This gives you a pretty nice debugging environment.  (You'll get a SIGHUP
00170  * early in standalone_main; just continue through.  This is the server
00171  * trying to kill off any child processes which it might have lying
00172  * around --- Apache doesn't keep track of their pids, it just sends
00173  * SIGHUP to the process group, ignoring it in the root process.
00174  * Continue through and you'll be fine.).
00175  */
00176 
00177 static int one_process = 0;
00178 
00179 #ifdef DEBUG_SIGSTOP
00180 int raise_sigstop_flags;
00181 #endif
00182 
00183 static apr_pool_t *pconf;                 /* Pool for config stuff */
00184 static apr_pool_t *pchild;                /* Pool for httpd child stuff */
00185 
00186 static pid_t ap_my_pid; /* Linux getpid() doesn't work except in main 
00187                            thread. Use this instead */
00188 static pid_t parent_pid;
00189 
00190 /* Locks for accept serialization */
00191 static apr_proc_mutex_t *accept_mutex;
00192 
00193 #ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
00194 #define SAFE_ACCEPT(stmt) (ap_listeners->next ? (stmt) : APR_SUCCESS)
00195 #else
00196 #define SAFE_ACCEPT(stmt) (stmt)
00197 #endif
00198 
00199 
00200 /* Structure used to wake up an idle worker thread
00201  */
00202 struct worker_wakeup_info {
00203     apr_uint32_t next; /* index into worker_wakeups array,
00204                         * used to build a linked list
00205                         */
00206     apr_thread_cond_t *cond;
00207     apr_thread_mutex_t *mutex;
00208 };
00209 
00210 static worker_wakeup_info *worker_wakeup_create(apr_pool_t *pool)
00211 {
00212     apr_status_t rv;
00213     worker_wakeup_info *wakeup;
00214 
00215     wakeup = (worker_wakeup_info *)apr_palloc(pool, sizeof(*wakeup));
00216     if ((rv = apr_thread_cond_create(&wakeup->cond, pool)) != APR_SUCCESS) {
00217         return NULL;
00218     }
00219     if ((rv = apr_thread_mutex_create(&wakeup->mutex, APR_THREAD_MUTEX_DEFAULT,
00220                                       pool)) != APR_SUCCESS) {
00221         return NULL;
00222     }
00223     /* The wakeup's mutex will be unlocked automatically when
00224      * the worker blocks on the condition variable
00225      */
00226     apr_thread_mutex_lock(wakeup->mutex);
00227     return wakeup;
00228 }
00229 
00230 
00231 /* Structure used to hold a stack of idle worker threads 
00232  */
00233 typedef struct {
00234     /* 'state' consists of several fields concatenated into a
00235      * single 32-bit int for use with the apr_atomic_cas() API:
00236      *   state & STACK_FIRST  is the thread ID of the first thread
00237      *                        in a linked list of idle threads
00238      *   state & STACK_TERMINATED  indicates whether the proc is shutting down
00239      *   state & STACK_NO_LISTENER indicates whether the process has
00240      *                             no current listener thread
00241      */
00242     apr_uint32_t state;
00243 } worker_stack;
00244 
00245 #define STACK_FIRST  0xffff
00246 #define STACK_LIST_END  0xffff
00247 #define STACK_TERMINATED 0x10000
00248 #define STACK_NO_LISTENER 0x20000
00249 
00250 static worker_wakeup_info **worker_wakeups = NULL;
00251 
00252 static worker_stack* worker_stack_create(apr_pool_t *pool, apr_size_t max)
00253 {
00254     worker_stack *stack = (worker_stack *)apr_palloc(pool, sizeof(*stack));
00255     stack->state = STACK_NO_LISTENER | STACK_LIST_END;
00256     return stack;
00257 }
00258 
00259 static apr_status_t worker_stack_wait(worker_stack *stack,
00260                                       apr_uint32_t worker_id)
00261 {
00262     worker_wakeup_info *wakeup = worker_wakeups[worker_id];
00263 
00264     while (1) {
00265         apr_uint32_t state = stack->state;
00266         if (state & (STACK_TERMINATED | STACK_NO_LISTENER)) {
00267             if (state & STACK_TERMINATED) {
00268                 return APR_EINVAL;
00269             }
00270             if (apr_atomic_cas(&(stack->state), STACK_LIST_END, state) !=
00271                 state) {
00272                 continue;
00273             }
00274             else {
00275                 return APR_SUCCESS;
00276             }
00277         }
00278         wakeup->next = state;
00279         if (apr_atomic_cas(&(stack->state), worker_id, state) != state) {
00280             continue;
00281         }
00282         else {
00283             return apr_thread_cond_wait(wakeup->cond, wakeup->mutex);
00284         }
00285     }    
00286 }
00287 
00288 static apr_status_t worker_stack_awaken_next(worker_stack *stack)
00289 {
00290 
00291     while (1) {
00292         apr_uint32_t state = stack->state;
00293         apr_uint32_t first = state & STACK_FIRST;
00294         if (first == STACK_LIST_END) {
00295             if (apr_atomic_cas(&(stack->state), state | STACK_NO_LISTENER,
00296                                state) != state) {
00297                 continue;
00298             }
00299             else {
00300                 return APR_SUCCESS;
00301             }
00302         }
00303         else {
00304             worker_wakeup_info *wakeup = worker_wakeups[first];
00305             if (apr_atomic_cas(&(stack->state), (state ^ first) | wakeup->next,
00306                                state) != state) {
00307                 continue;
00308             }
00309             else {
00310                 /* Acquire and release the idle worker's mutex to ensure
00311                  * that it's actually waiting on its condition variable
00312                  */
00313                 apr_status_t rv;
00314                 if ((rv = apr_thread_mutex_lock(wakeup->mutex)) !=
00315                     APR_SUCCESS) {
00316                     return rv;
00317                 }
00318                 if ((rv = apr_thread_mutex_unlock(wakeup->mutex)) !=
00319                     APR_SUCCESS) {
00320                     return rv;
00321                 }
00322                 return apr_thread_cond_signal(wakeup->cond);
00323             }
00324         }
00325     }
00326 }
00327 
00328 static apr_status_t worker_stack_term(worker_stack *stack)
00329 {
00330     int i;
00331     apr_status_t rv;
00332 
00333     while (1) {
00334         apr_uint32_t state = stack->state;
00335         if (apr_atomic_cas(&(stack->state), state | STACK_TERMINATED,
00336                            state) == state) {
00337             break;
00338         }
00339     }
00340     for (i = 0; i < ap_threads_per_child; i++) {
00341         if ((rv = worker_stack_awaken_next(stack)) != APR_SUCCESS) {
00342             return rv;
00343         }
00344     }
00345     return APR_SUCCESS;
00346 }
00347 
00348 static worker_stack *idle_worker_stack;
00349 
00350 #define ST_INIT              0
00351 #define ST_GRACEFUL          1
00352 #define ST_UNGRACEFUL        2
00353 
00354 static int terminate_mode = ST_INIT;
00355 
00356 static void signal_threads(int mode)
00357 {
00358     if (terminate_mode == mode) {
00359         return;
00360     }
00361     terminate_mode = mode;
00362     mpm_state = AP_MPMQ_STOPPING;
00363     workers_may_exit = 1;
00364 
00365     worker_stack_term(idle_worker_stack);
00366 }
00367 
00368 AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
00369 {
00370     switch(query_code){
00371         case AP_MPMQ_MAX_DAEMON_USED:
00372             *result = ap_max_daemons_limit;
00373             return APR_SUCCESS;
00374         case AP_MPMQ_IS_THREADED:
00375             *result = AP_MPMQ_STATIC;
00376             return APR_SUCCESS;
00377         case AP_MPMQ_IS_FORKED:
00378             *result = AP_MPMQ_DYNAMIC;
00379             return APR_SUCCESS;
00380         case AP_MPMQ_HARD_LIMIT_DAEMONS:
00381             *result = server_limit;
00382             return APR_SUCCESS;
00383         case AP_MPMQ_HARD_LIMIT_THREADS:
00384             *result = thread_limit;
00385             return APR_SUCCESS;
00386         case AP_MPMQ_MAX_THREADS:
00387             *result = ap_threads_per_child;
00388             return APR_SUCCESS;
00389         case AP_MPMQ_MIN_SPARE_DAEMONS:
00390             *result = 0;
00391             return APR_SUCCESS;
00392         case AP_MPMQ_MIN_SPARE_THREADS:    
00393             *result = min_spare_threads;
00394             return APR_SUCCESS;
00395         case AP_MPMQ_MAX_SPARE_DAEMONS:
00396             *result = 0;
00397             return APR_SUCCESS;
00398         case AP_MPMQ_MAX_SPARE_THREADS:
00399             *result = max_spare_threads;
00400             return APR_SUCCESS;
00401         case AP_MPMQ_MAX_REQUESTS_DAEMON:
00402             *result = ap_max_requests_per_child;
00403             return APR_SUCCESS;
00404         case AP_MPMQ_MAX_DAEMONS:
00405             *result = ap_daemons_limit;
00406             return APR_SUCCESS;
00407         case AP_MPMQ_MPM_STATE:
00408             *result = mpm_state;
00409             return APR_SUCCESS;
00410     }
00411     return APR_ENOTIMPL;
00412 }
00413 
00414 /* a clean exit from a child with proper cleanup */ 
00415 static void clean_child_exit(int code) __attribute__ ((noreturn));
00416 static void clean_child_exit(int code)
00417 {
00418     mpm_state = AP_MPMQ_STOPPING;
00419     if (pchild) {
00420         apr_pool_destroy(pchild);
00421     }
00422     ap_mpm_pod_close(pod);
00423     exit(code);
00424 }
00425 
00426 static void just_die(int sig)
00427 {
00428     clean_child_exit(0);
00429 }
00430 
00431 /*****************************************************************
00432  * Connection structures and accounting...
00433  */
00434 
00435 /* volatile just in case */
00436 static int volatile shutdown_pending;
00437 static int volatile restart_pending;
00438 static int volatile is_graceful;
00439 static volatile int child_fatal;
00440 ap_generation_t volatile ap_my_generation;
00441 
00442 /*
00443  * ap_start_shutdown() and ap_start_restart(), below, are a first stab at
00444  * functions to initiate shutdown or restart without relying on signals. 
00445  * Previously this was initiated in sig_term() and restart() signal handlers, 
00446  * but we want to be able to start a shutdown/restart from other sources --
00447  * e.g. on Win32, from the service manager. Now the service manager can
00448  * call ap_start_shutdown() or ap_start_restart() as appropiate.  Note that
00449  * these functions can also be called by the child processes, since global
00450  * variables are no longer used to pass on the required action to the parent.
00451  *
00452  * These should only be called from the parent process itself, since the
00453  * parent process will use the shutdown_pending and restart_pending variables
00454  * to determine whether to shutdown or restart. The child process should
00455  * call signal_parent() directly to tell the parent to die -- this will
00456  * cause neither of those variable to be set, which the parent will
00457  * assume means something serious is wrong (which it will be, for the
00458  * child to force an exit) and so do an exit anyway.
00459  */
00460 
00461 static void ap_start_shutdown(void)
00462 {
00463     mpm_state = AP_MPMQ_STOPPING;
00464     if (shutdown_pending == 1) {
00465         /* Um, is this _probably_ not an error, if the user has
00466          * tried to do a shutdown twice quickly, so we won't
00467          * worry about reporting it.
00468          */
00469         return;
00470     }
00471     shutdown_pending = 1;
00472 }
00473 
00474 /* do a graceful restart if graceful == 1 */
00475 static void ap_start_restart(int graceful)
00476 {
00477     mpm_state = AP_MPMQ_STOPPING;
00478     if (restart_pending == 1) {
00479         /* Probably not an error - don't bother reporting it */
00480         return;
00481     }
00482     restart_pending = 1;
00483     is_graceful = graceful;
00484 }
00485 
00486 static void sig_term(int sig)
00487 {
00488     if (ap_my_pid == parent_pid) {
00489         ap_start_shutdown();
00490     }
00491     else {
00492         signal_threads(ST_GRACEFUL);
00493     }
00494 }
00495 
00496 static void restart(int sig)
00497 {
00498     ap_start_restart(sig == AP_SIG_GRACEFUL);
00499 }
00500 
00501 static void set_signals(void)
00502 {
00503 #ifndef NO_USE_SIGACTION
00504     struct sigaction sa;
00505 #endif
00506 
00507     if (!one_process) {
00508         ap_fatal_signal_setup(ap_server_conf, pconf);
00509     }
00510 
00511 #ifndef NO_USE_SIGACTION
00512     sigemptyset(&sa.sa_mask);
00513     sa.sa_flags = 0;
00514 
00515     sa.sa_handler = sig_term;
00516     if (sigaction(SIGTERM, &sa, NULL) < 0)
00517         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, 
00518                      "sigaction(SIGTERM)");
00519 #ifdef SIGINT
00520     if (sigaction(SIGINT, &sa, NULL) < 0)
00521         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, 
00522                      "sigaction(SIGINT)");
00523 #endif
00524 #ifdef SIGXCPU
00525     sa.sa_handler = SIG_DFL;
00526     if (sigaction(SIGXCPU, &sa, NULL) < 0)
00527         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, 
00528                      "sigaction(SIGXCPU)");
00529 #endif
00530 #ifdef SIGXFSZ
00531     sa.sa_handler = SIG_DFL;
00532     if (sigaction(SIGXFSZ, &sa, NULL) < 0)
00533         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, 
00534                      "sigaction(SIGXFSZ)");
00535 #endif
00536 #ifdef SIGPIPE
00537     sa.sa_handler = SIG_IGN;
00538     if (sigaction(SIGPIPE, &sa, NULL) < 0)
00539         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, 
00540                      "sigaction(SIGPIPE)");
00541 #endif
00542 
00543     /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy 
00544      * processing one */
00545     sigaddset(&sa.sa_mask, SIGHUP);
00546     sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL);
00547     sa.sa_handler = restart;
00548     if (sigaction(SIGHUP, &sa, NULL) < 0)
00549         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, 
00550                      "sigaction(SIGHUP)");
00551     if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0)
00552         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, 
00553                      "sigaction(" AP_SIG_GRACEFUL_STRING ")");
00554 #else
00555     if (!one_process) {
00556 #ifdef SIGXCPU
00557         apr_signal(SIGXCPU, SIG_DFL);
00558 #endif /* SIGXCPU */
00559 #ifdef SIGXFSZ
00560         apr_signal(SIGXFSZ, SIG_DFL);
00561 #endif /* SIGXFSZ */
00562     }
00563 
00564     apr_signal(SIGTERM, sig_term);
00565 #ifdef SIGHUP
00566     apr_signal(SIGHUP, restart);
00567 #endif /* SIGHUP */
00568 #ifdef AP_SIG_GRACEFUL
00569     apr_signal(AP_SIG_GRACEFUL, restart);
00570 #endif /* AP_SIG_GRACEFUL */
00571 #ifdef SIGPIPE
00572     apr_signal(SIGPIPE, SIG_IGN);
00573 #endif /* SIGPIPE */
00574 
00575 #endif
00576 }
00577 
00578 /*****************************************************************
00579  * Here follows a long bunch of generic server bookkeeping stuff...
00580  */
00581 
00582 int ap_graceful_stop_signalled(void)
00583     /* XXX this is really a bad confusing obsolete name
00584      * maybe it should be ap_mpm_process_exiting?
00585      */
00586 {
00587     return workers_may_exit;
00588 }
00589 
00590 /*****************************************************************
00591  * Child process main loop.
00592  */
00593 
00594 static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num,
00595                            int my_thread_num, apr_bucket_alloc_t *bucket_alloc)
00596 {
00597     conn_rec *current_conn;
00598     long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num);
00599     int csd;
00600     ap_sb_handle_t *sbh;
00601 
00602     ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num);
00603     apr_os_sock_get(&csd, sock);
00604 
00605     current_conn = ap_run_create_connection(p, ap_server_conf, sock,
00606                                             conn_id, sbh, bucket_alloc);
00607     if (current_conn) {
00608         ap_process_connection(current_conn, sock);
00609         ap_lingering_close(current_conn);
00610     }
00611 }
00612 
00613 /* requests_this_child has gone to zero or below.  See if the admin coded
00614    "MaxRequestsPerChild 0", and keep going in that case.  Doing it this way
00615    simplifies the hot path in worker_thread */
00616 static void check_infinite_requests(void)
00617 {
00618     if (ap_max_requests_per_child) {
00619         signal_threads(ST_GRACEFUL);
00620     }
00621     else {
00622         /* wow! if you're executing this code, you may have set a record.
00623          * either this child process has served over 2 billion requests, or
00624          * you're running a threaded 2.0 on a 16 bit machine.  
00625          *
00626          * I'll buy pizza and beers at Apachecon for the first person to do
00627          * the former without cheating (dorking with INT_MAX, or running with
00628          * uncommitted performance patches, for example).    
00629          *
00630          * for the latter case, you probably deserve a beer too.   Greg Ames
00631          */
00632             
00633         requests_this_child = INT_MAX;      /* keep going */ 
00634     }
00635 }
00636 
00637 static void unblock_signal(int sig)
00638 {
00639     sigset_t sig_mask;
00640 
00641     sigemptyset(&sig_mask);
00642     sigaddset(&sig_mask, sig);
00643 #if defined(SIGPROCMASK_SETS_THREAD_MASK)
00644     sigprocmask(SIG_UNBLOCK, &sig_mask, NULL);
00645 #else
00646     pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL);
00647 #endif
00648 }
00649 
00650 static void *worker_thread(apr_thread_t *thd, void * dummy)
00651 {
00652     proc_info * ti = dummy;
00653     int process_slot = ti->pid;
00654     int thread_slot = ti->tid;
00655     apr_uint32_t my_worker_num = (apr_uint32_t)(ti->tid);
00656     apr_pool_t *tpool = apr_thread_pool_get(thd);
00657     void *csd = NULL;
00658     apr_allocator_t *allocator;
00659     apr_pool_t *ptrans;                /* Pool for per-transaction stuff */
00660     apr_bucket_alloc_t *bucket_alloc;
00661     int n;
00662     apr_pollfd_t *pollset;
00663     apr_status_t rv;
00664     ap_listen_rec *lr, *last_lr = ap_listeners;
00665     int is_listener;
00666 
00667     ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL);
00668 
00669     free(ti);
00670 
00671     apr_allocator_create(&allocator);
00672     apr_allocator_max_free_set(allocator, ap_max_mem_free);
00673     /* XXX: why is ptrans's parent not tpool?  --jcw 08/2003 */
00674     apr_pool_create_ex(&ptrans, NULL, NULL, allocator);
00675     apr_allocator_owner_set(allocator, ptrans);
00676     bucket_alloc = apr_bucket_alloc_create_ex(allocator);
00677 
00678     apr_poll_setup(&pollset, num_listensocks, tpool);
00679     for(lr = ap_listeners ; lr != NULL ; lr = lr->next)
00680         apr_poll_socket_add(pollset, lr->sd, APR_POLLIN);
00681 
00682     /* TODO: Switch to a system where threads reuse the results from earlier
00683        poll calls - manoj */
00684     is_listener = 0;
00685     while (!workers_may_exit) {
00686 
00687         ap_update_child_status_from_indexes(process_slot, thread_slot,
00688                                             SERVER_READY, NULL);
00689         if (!is_listener) {
00690             /* Wait until it's our turn to become the listener */
00691             if ((rv = worker_stack_wait(idle_worker_stack, my_worker_num)) !=
00692                 APR_SUCCESS) {
00693                 if (rv != APR_EINVAL) {
00694                     ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
00695                                  "worker_stack_wait failed. Shutting down");
00696                 }
00697                 break;
00698             }
00699             if (workers_may_exit) {
00700                 break;
00701             }
00702             is_listener = 1;
00703         }
00704 
00705         /* TODO: requests_this_child should be synchronized - aaron */
00706         if (requests_this_child <= 0) {
00707             check_infinite_requests();
00708         }
00709         if (workers_may_exit) break;
00710 
00711         if ((rv = SAFE_ACCEPT(apr_proc_mutex_lock(accept_mutex)))
00712             != APR_SUCCESS) {
00713             int level = APLOG_EMERG;
00714 
00715             if (workers_may_exit) {
00716                 break;
00717             }
00718             if (ap_scoreboard_image->parent[process_slot].generation != 
00719                 ap_scoreboard_image->global->running_generation) {
00720                 level = APLOG_DEBUG; /* common to get these at restart time */
00721             }
00722             ap_log_error(APLOG_MARK, level, rv, ap_server_conf,
00723                          "apr_proc_mutex_lock failed. Attempting to shutdown "
00724                          "process gracefully.");
00725             signal_threads(ST_GRACEFUL);
00726             break;                    /* skip the lock release */
00727         }
00728 
00729         if (!ap_listeners->next) {
00730             /* Only one listener, so skip the poll */
00731             lr = ap_listeners;
00732         }
00733         else {
00734             while (!workers_may_exit) {
00735                 apr_status_t ret;
00736                 apr_int16_t event;
00737 
00738                 ret = apr_poll(pollset, num_listensocks, &n, -1);
00739                 if (ret != APR_SUCCESS) {
00740                     if (APR_STATUS_IS_EINTR(ret)) {
00741                         continue;
00742                     }
00743 
00744                     /* apr_poll() will only return errors in catastrophic
00745                      * circumstances. Let's try exiting gracefully, for now. */
00746                     ap_log_error(APLOG_MARK, APLOG_ERR, ret, (const server_rec *)
00747                                  ap_server_conf, "apr_poll: (listen)");
00748                     signal_threads(ST_GRACEFUL);
00749                 }
00750 
00751                 if (workers_may_exit) break;
00752 
00753                 /* find a listener */
00754                 lr = last_lr;
00755                 do {
00756                     lr = lr->next;
00757                     if (lr == NULL) {
00758                         lr = ap_listeners;
00759                     }
00760                     /* XXX: Should we check for POLLERR? */
00761                     apr_poll_revents_get(&event, lr->sd, pollset);
00762                     if (event & APR_POLLIN) {
00763                         last_lr = lr;
00764                         goto got_fd;
00765                     }
00766                 } while (lr != last_lr);
00767             }
00768         }
00769     got_fd:
00770         if (!workers_may_exit) {
00771             rv = lr->accept_func(&csd, lr, ptrans);
00772             /* later we trash rv and rely on csd to indicate success/failure */
00773             AP_DEBUG_ASSERT(rv == APR_SUCCESS || !csd);
00774 
00775             if (rv == APR_EGENERAL) {
00776                 /* E[NM]FILE, ENOMEM, etc */
00777                 resource_shortage = 1;
00778                 signal_threads(ST_GRACEFUL);
00779             }
00780             if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex)))
00781                 != APR_SUCCESS) {
00782                 int level = APLOG_EMERG;
00783 
00784                 if (workers_may_exit) {
00785                     break;
00786                 }
00787                 if (ap_scoreboard_image->parent[process_slot].generation != 
00788                     ap_scoreboard_image->global->running_generation) {
00789                     level = APLOG_DEBUG; /* common to get these at restart time */
00790                 }
00791                 ap_log_error(APLOG_MARK, level, rv, ap_server_conf,
00792                              "apr_proc_mutex_unlock failed. Attempting to "
00793                              "shutdown process gracefully.");
00794                 signal_threads(ST_GRACEFUL);
00795             }
00796             if (csd != NULL) {
00797                 is_listener = 0;
00798                 worker_stack_awaken_next(idle_worker_stack);
00799                 process_socket(ptrans, csd, process_slot,
00800                                thread_slot, bucket_alloc);
00801                 apr_pool_clear(ptrans);
00802                 requests_this_child--;
00803             }
00804             if ((ap_mpm_pod_check(pod) == APR_SUCCESS) ||
00805                 (ap_my_generation !=
00806                  ap_scoreboard_image->global->running_generation)) {
00807                 signal_threads(ST_GRACEFUL);
00808                 break;
00809             }
00810         }
00811         else {
00812             if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex)))
00813                 != APR_SUCCESS) {
00814                 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
00815                              "apr_proc_mutex_unlock failed. Attempting to "
00816                              "shutdown process gracefully.");
00817                 signal_threads(ST_GRACEFUL);
00818             }
00819             break;
00820         }
00821     }
00822 
00823     dying = 1;
00824     ap_scoreboard_image->parent[process_slot].quiescing = 1;
00825 
00826     worker_stack_term(idle_worker_stack);
00827 
00828     ap_update_child_status_from_indexes(process_slot, thread_slot,
00829         (dying) ? SERVER_DEAD : SERVER_GRACEFUL, (request_rec *) NULL);
00830 
00831     apr_bucket_alloc_destroy(bucket_alloc);
00832 
00833     apr_thread_exit(thd, APR_SUCCESS);
00834     return NULL;
00835 }
00836 
00837 static int check_signal(int signum)
00838 {
00839     switch (signum) {
00840     case SIGTERM:
00841     case SIGINT:
00842         return 1;
00843     }
00844     return 0;
00845 }
00846 
00847 /* XXX under some circumstances not understood, children can get stuck
00848  *     in start_threads forever trying to take over slots which will
00849  *     never be cleaned up; for now there is an APLOG_DEBUG message issued
00850  *     every so often when this condition occurs
00851  */
00852 static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy)
00853 {
00854     thread_starter *ts = dummy;
00855     apr_thread_t **threads = ts->threads;
00856     apr_threadattr_t *thread_attr = ts->threadattr;
00857     int child_num_arg = ts->child_num_arg;
00858     int my_child_num = child_num_arg;
00859     proc_info *my_info;
00860     apr_status_t rv;
00861     int i;
00862     int threads_created = 0;
00863     int loops;
00864     int prev_threads_created;
00865 
00866     idle_worker_stack = worker_stack_create(pchild, ap_threads_per_child);
00867     if (idle_worker_stack == NULL) {
00868         ap_log_error(APLOG_MARK, APLOG_ALERT, 0, ap_server_conf,
00869                      "worker_stack_create() failed");
00870         clean_child_exit(APEXIT_CHILDFATAL);
00871     }
00872 
00873     worker_wakeups = (worker_wakeup_info **)
00874         apr_palloc(pchild, sizeof(worker_wakeup_info *) *
00875                    ap_threads_per_child);
00876 
00877     loops = prev_threads_created = 0;
00878     while (1) {
00879         for (i = 0; i < ap_threads_per_child; i++) {
00880             int status = ap_scoreboard_image->servers[child_num_arg][i].status;
00881             worker_wakeup_info *wakeup;
00882 
00883             if (status != SERVER_GRACEFUL && status != SERVER_DEAD) {
00884                 continue;
00885             }
00886 
00887             wakeup = worker_wakeup_create(pchild);
00888             if (wakeup == NULL) {
00889                 ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, 0,
00890                              ap_server_conf, "worker_wakeup_create failed");
00891                 clean_child_exit(APEXIT_CHILDFATAL);
00892             }
00893             worker_wakeups[threads_created] = wakeup;
00894             my_info = (proc_info *)malloc(sizeof(proc_info));
00895             if (my_info == NULL) {
00896                 ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf,
00897                              "malloc: out of memory");
00898                 clean_child_exit(APEXIT_CHILDFATAL);
00899             }
00900             my_info->pid = my_child_num;
00901             my_info->tid = i;
00902             my_info->sd = 0;
00903         
00904             /* We are creating threads right now */
00905             ap_update_child_status_from_indexes(my_child_num, i,
00906                                                 SERVER_STARTING, NULL);
00907             /* We let each thread update its own scoreboard entry.  This is
00908              * done because it lets us deal with tid better.
00909              */
00910             rv = apr_thread_create(&threads[i], thread_attr, 
00911                                    worker_thread, my_info, pchild);
00912             if (rv != APR_SUCCESS) {
00913                 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
00914                     "apr_thread_create: unable to create worker thread");
00915                 /* In case system resources are maxxed out, we don't want
00916                    Apache running away with the CPU trying to fork over and
00917                    over and over again if we exit. */
00918                 apr_sleep(10 * APR_USEC_PER_SEC);
00919                 clean_child_exit(APEXIT_CHILDFATAL);
00920             }
00921             threads_created++;
00922         }
00923         if (start_thread_may_exit || threads_created == ap_threads_per_child) {
00924             break;
00925         }
00926         /* wait for previous generation to clean up an entry */
00927         apr_sleep(1 * APR_USEC_PER_SEC);
00928         ++loops;
00929         if (loops % 120 == 0) { /* every couple of minutes */
00930             if (prev_threads_created == threads_created) {
00931                 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
00932                              "child %" APR_PID_T_FMT " isn't taking over "
00933                              "slots very quickly (%d of %d)",
00934                              ap_my_pid, threads_created, ap_threads_per_child);
00935             }
00936             prev_threads_created = threads_created;
00937         }
00938     }
00939     
00940     /* What state should this child_main process be listed as in the 
00941      * scoreboard...?
00942      *  ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING, 
00943      *                                      (request_rec *) NULL);
00944      * 
00945      *  This state should be listed separately in the scoreboard, in some kind
00946      *  of process_status, not mixed in with the worker threads' status.   
00947      *  "life_status" is almost right, but it's in the worker's structure, and 
00948      *  the name could be clearer.   gla
00949      */
00950     apr_thread_exit(thd, APR_SUCCESS);
00951     return NULL;
00952 }
00953 
00954 static void join_workers(apr_thread_t **threads)
00955 {
00956     int i;
00957     apr_status_t rv, thread_rv;
00958 
00959     for (i = 0; i < ap_threads_per_child; i++) {
00960         if (threads[i]) { /* if we ever created this thread */
00961             rv = apr_thread_join(&thread_rv, threads[i]);
00962             if (rv != APR_SUCCESS) {
00963                 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
00964                              "apr_thread_join: unable to join worker "
00965                              "thread %d",
00966                              i);
00967             }
00968         }
00969     }
00970 }
00971 
00972 static void join_start_thread(apr_thread_t *start_thread_id)
00973 {
00974     apr_status_t rv, thread_rv;
00975 
00976     start_thread_may_exit = 1; /* tell it to give up in case it is still 
00977                                 * trying to take over slots from a 
00978                                 * previous generation
00979                                 */
00980     rv = apr_thread_join(&thread_rv, start_thread_id);
00981     if (rv != APR_SUCCESS) {
00982         ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
00983                      "apr_thread_join: unable to join the start "
00984                      "thread");
00985     }
00986 }
00987 
00988 static void child_main(int child_num_arg)
00989 {
00990     apr_thread_t **threads;
00991     apr_status_t rv;
00992     thread_starter *ts;
00993     apr_threadattr_t *thread_attr;
00994     apr_thread_t *start_thread_id;
00995 
00996     mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
00997                                   * child initializes
00998                                   */
00999 
01000     ap_my_pid = getpid();
01001     ap_fatal_signal_child_setup(ap_server_conf);
01002     apr_pool_create(&pchild, pconf);
01003 
01004     /*stuff to do before we switch id's, so we have permissions.*/
01005     ap_reopen_scoreboard(pchild, NULL, 0);
01006 
01007     rv = SAFE_ACCEPT(apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname,
01008                                                pchild));
01009     if (rv != APR_SUCCESS) {
01010         ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
01011                      "Couldn't initialize cross-process lock in child");
01012         clean_child_exit(APEXIT_CHILDFATAL);
01013     }
01014 
01015     if (unixd_setup_child()) {
01016         clean_child_exit(APEXIT_CHILDFATAL);
01017     }
01018 
01019     ap_run_child_init(pchild, ap_server_conf);
01020 
01021     /* done with init critical section */
01022 
01023     /* Just use the standard apr_setup_signal_thread to block all signals
01024      * from being received.  The child processes no longer use signals for
01025      * any communication with the parent process.
01026      */
01027     rv = apr_setup_signal_thread();
01028     if (rv != APR_SUCCESS) {
01029         ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
01030                      "Couldn't initialize signal thread");
01031         clean_child_exit(APEXIT_CHILDFATAL);
01032     }
01033 
01034     if (ap_max_requests_per_child) {
01035         requests_this_child = ap_max_requests_per_child;
01036     }
01037     else {
01038         /* coding a value of zero means infinity */
01039         requests_this_child = INT_MAX;
01040     }
01041     
01042     /* Setup worker threads */
01043 
01044     /* clear the storage; we may not create all our threads immediately, 
01045      * and we want a 0 entry to indicate a thread which was not created
01046      */
01047     threads = (apr_thread_t **)calloc(1, 
01048                                 sizeof(apr_thread_t *) * ap_threads_per_child);
01049     if (threads == NULL) {
01050         ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf,
01051                      "malloc: out of memory");
01052         clean_child_exit(APEXIT_CHILDFATAL);
01053     }
01054 
01055     ts = (thread_starter *)apr_palloc(pchild, sizeof(*ts));
01056 
01057     apr_threadattr_create(&thread_attr, pchild);
01058     /* 0 means PTHREAD_CREATE_JOINABLE */
01059     apr_threadattr_detach_set(thread_attr, 0);
01060 
01061     ts->threads = threads;
01062     ts->child_num_arg = child_num_arg;
01063     ts->threadattr = thread_attr;
01064 
01065     rv = apr_thread_create(&start_thread_id, thread_attr, start_threads,
01066                            ts, pchild);
01067     if (rv != APR_SUCCESS) {
01068         ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
01069                      "apr_thread_create: unable to create worker thread");
01070         /* In case system resources are maxxed out, we don't want
01071            Apache running away with the CPU trying to fork over and
01072            over and over again if we exit. */
01073         apr_sleep(10 * APR_USEC_PER_SEC);
01074         clean_child_exit(APEXIT_CHILDFATAL);
01075     }
01076 
01077     mpm_state = AP_MPMQ_RUNNING;
01078 
01079     /* If we are only running in one_process mode, we will want to
01080      * still handle signals. */
01081     if (one_process) {
01082         /* Block until we get a terminating signal. */
01083         apr_signal_thread(check_signal);
01084         /* make sure the start thread has finished; signal_threads() 
01085          * and join_workers() depend on that
01086          */
01087         /* XXX join_start_thread() won't be awakened if one of our
01088          *     threads encounters a critical error and attempts to
01089          *     shutdown this child
01090          */
01091         join_start_thread(start_thread_id);
01092         signal_threads(ST_UNGRACEFUL); /* helps us terminate a little more
01093                            * quickly than the dispatch of the signal thread
01094                            * beats the Pipe of Death and the browsers
01095                            */
01096         /* A terminating signal was received. Now join each of the
01097          * workers to clean them up.
01098          *   If the worker already exited, then the join frees
01099          *   their resources and returns.
01100          *   If the worker hasn't exited, then this blocks until
01101          *   they have (then cleans up).
01102          */
01103         join_workers(threads);
01104     }
01105     else { /* !one_process */
01106         /* remove SIGTERM from the set of blocked signals...  if one of
01107          * the other threads in the process needs to take us down
01108          * (e.g., for MaxRequestsPerChild) it will send us SIGTERM
01109          */
01110         unblock_signal(SIGTERM);
01111         join_start_thread(start_thread_id);
01112         join_workers(threads);
01113     }
01114 
01115     free(threads);
01116 
01117     clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0);
01118 }
01119 
01120 static int make_child(server_rec *s, int slot) 
01121 {
01122     int pid;
01123 
01124     if (slot + 1 > ap_max_daemons_limit) {
01125         ap_max_daemons_limit = slot + 1;
01126     }
01127 
01128     if (one_process) {
01129         set_signals();
01130         ap_scoreboard_image->parent[slot].pid = getpid();
01131         child_main(slot);
01132     }
01133 
01134     if ((pid = fork()) == -1) {
01135         ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, 
01136                      "fork: Unable to fork new process");
01137 
01138         /* fork didn't succeed. Fix the scoreboard or else
01139          * it will say SERVER_STARTING forever and ever
01140          */
01141         ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, NULL);
01142 
01143         /* In case system resources are maxxed out, we don't want
01144            Apache running away with the CPU trying to fork over and
01145            over and over again. */
01146         apr_sleep(10 * APR_USEC_PER_SEC);
01147 
01148         return -1;
01149     }
01150 
01151     if (!pid) {
01152 #ifdef HAVE_BINDPROCESSOR
01153         /* By default, AIX binds to a single processor.  This bit unbinds
01154          * children which will then bind to another CPU.
01155          */
01156         int status = bindprocessor(BINDPROCESS, (int)getpid(),
01157                                PROCESSOR_CLASS_ANY);
01158         if (status != OK)
01159             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, 
01160                          ap_server_conf,
01161                          "processor unbind failed %d", status);
01162 #endif
01163         RAISE_SIGSTOP(MAKE_CHILD);
01164 
01165         apr_signal(SIGTERM, just_die);
01166         child_main(slot);
01167 
01168         clean_child_exit(0);
01169     }
01170     /* else */
01171     ap_scoreboard_image->parent[slot].quiescing = 0;
01172     ap_scoreboard_image->parent[slot].pid = pid;
01173     return 0;
01174 }
01175 
01176 /* start up a bunch of children */
01177 static void startup_children(int number_to_start)
01178 {
01179     int i;
01180 
01181     for (i = 0; number_to_start && i < ap_daemons_limit; ++i) {
01182         if (ap_scoreboard_image->parent[i].pid != 0) {
01183             continue;
01184         }
01185         if (make_child(ap_server_conf, i) < 0) {
01186             break;
01187         }
01188         --number_to_start;
01189     }
01190 }
01191 
01192 
01193 /*
01194  * idle_spawn_rate is the number of children that will be spawned on the
01195  * next maintenance cycle if there aren't enough idle servers.  It is
01196  * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
01197  * without the need to spawn.
01198  */
01199 static int idle_spawn_rate = 1;
01200 #ifndef MAX_SPAWN_RATE
01201 #define MAX_SPAWN_RATE        (32)
01202 #endif
01203 static int hold_off_on_exponential_spawning;
01204 
01205 static void perform_idle_server_maintenance(void)
01206 {
01207     int i, j;
01208     int idle_thread_count;
01209     worker_score *ws;
01210     process_score *ps;
01211     int free_length;
01212     int totally_free_length = 0;
01213     int free_slots[MAX_SPAWN_RATE];
01214     int last_non_dead;
01215     int total_non_dead;
01216 
01217     /* initialize the free_list */
01218     free_length = 0;
01219 
01220     idle_thread_count = 0;
01221     last_non_dead = -1;
01222     total_non_dead = 0;
01223 
01224     for (i = 0; i < ap_daemons_limit; ++i) {
01225         /* Initialization to satisfy the compiler. It doesn't know
01226          * that ap_threads_per_child is always > 0 */
01227         int status = SERVER_DEAD;
01228         int any_dying_threads = 0;
01229         int any_dead_threads = 0;
01230         int all_dead_threads = 1;
01231 
01232         if (i >= ap_max_daemons_limit && totally_free_length == idle_spawn_rate)
01233             break;
01234         ps = &ap_scoreboard_image->parent[i];
01235         for (j = 0; j < ap_threads_per_child; j++) {
01236             ws = &ap_scoreboard_image->servers[i][j];
01237             status = ws->status;
01238 
01239             /* XXX any_dying_threads is probably no longer needed    GLA */
01240             any_dying_threads = any_dying_threads || 
01241                                 (status == SERVER_GRACEFUL);
01242             any_dead_threads = any_dead_threads || (status == SERVER_DEAD);
01243             all_dead_threads = all_dead_threads &&
01244                                    (status == SERVER_DEAD ||
01245                                     status == SERVER_GRACEFUL);
01246 
01247             /* We consider a starting server as idle because we started it
01248              * at least a cycle ago, and if it still hasn't finished starting
01249              * then we're just going to swamp things worse by forking more.
01250              * So we hopefully won't need to fork more if we count it.
01251              * This depends on the ordering of SERVER_READY and SERVER_STARTING.
01252              */
01253             if (status <= SERVER_READY && status != SERVER_DEAD &&
01254                     !ps->quiescing &&
01255                     ps->generation == ap_my_generation &&
01256                  /* XXX the following shouldn't be necessary if we clean up 
01257                   *     properly after seg faults, but we're not yet    GLA 
01258                   */     
01259                     ps->pid != 0) {
01260                 ++idle_thread_count;
01261             }
01262         }
01263         if (any_dead_threads && totally_free_length < idle_spawn_rate 
01264                 && (!ps->pid               /* no process in the slot */
01265                     || ps->quiescing)) {   /* or at least one is going away */
01266             if (all_dead_threads) {
01267                 /* great! we prefer these, because the new process can
01268                  * start more threads sooner.  So prioritize this slot 
01269                  * by putting it ahead of any slots with active threads.
01270                  *
01271                  * first, make room by moving a slot that's potentially still
01272                  * in use to the end of the array
01273                  */
01274                 free_slots[free_length] = free_slots[totally_free_length];
01275                 free_slots[totally_free_length++] = i;
01276             }
01277             else {
01278                 /* slot is still in use - back of the bus
01279                  */
01280             free_slots[free_length] = i;
01281             }
01282             ++free_length;
01283         }
01284         /* XXX if (!ps->quiescing)     is probably more reliable  GLA */
01285         if (!any_dying_threads) {
01286             last_non_dead = i;
01287             ++total_non_dead;
01288         }
01289     }
01290     ap_max_daemons_limit = last_non_dead + 1;
01291 
01292     if (idle_thread_count > max_spare_threads) {
01293         /* Kill off one child */
01294         ap_mpm_pod_signal(pod);
01295         idle_spawn_rate = 1;
01296     }
01297     else if (idle_thread_count < min_spare_threads) {
01298         /* terminate the free list */
01299         if (free_length == 0) {
01300             /* only report this condition once */
01301             static int reported = 0;
01302             
01303             if (!reported) {
01304                 ap_log_error(APLOG_MARK, APLOG_ERR, 0, 
01305                              ap_server_conf,
01306                              "server reached MaxClients setting, consider"
01307                              " raising the MaxClients setting");
01308                 reported = 1;
01309             }
01310             idle_spawn_rate = 1;
01311         }
01312         else {
01313             if (free_length > idle_spawn_rate) {
01314                 free_length = idle_spawn_rate;
01315             }
01316             if (idle_spawn_rate >= 8) {
01317                 ap_log_error(APLOG_MARK, APLOG_INFO, 0, 
01318                              ap_server_conf,
01319                              "server seems busy, (you may need "
01320                              "to increase StartServers, ThreadsPerChild "
01321                              "or Min/MaxSpareThreads), "
01322                              "spawning %d children, there are around %d idle "
01323                              "threads, and %d total children", free_length,
01324                              idle_thread_count, total_non_dead);
01325             }
01326             for (i = 0; i < free_length; ++i) {
01327                 make_child(ap_server_conf, free_slots[i]);
01328             }
01329             /* the next time around we want to spawn twice as many if this
01330              * wasn't good enough, but not if we've just done a graceful
01331              */
01332             if (hold_off_on_exponential_spawning) {
01333                 --hold_off_on_exponential_spawning;
01334             }
01335             else if (idle_spawn_rate < MAX_SPAWN_RATE) {
01336                 idle_spawn_rate *= 2;
01337             }
01338         }
01339     }
01340     else {
01341       idle_spawn_rate = 1;
01342     }
01343 }
01344 
01345 static void server_main_loop(int remaining_children_to_start)
01346 {
01347     int child_slot;
01348     apr_exit_why_e exitwhy;
01349     int status, processed_status;
01350     apr_proc_t pid;
01351     int i;
01352 
01353     while (!restart_pending && !shutdown_pending) {
01354         ap_wait_or_timeout(&exitwhy, &status, &pid, pconf);
01355         
01356         if (pid.pid != -1) {
01357             processed_status = ap_process_child_status(&pid, exitwhy, status);
01358             if (processed_status == APEXIT_CHILDFATAL) {
01359                 shutdown_pending = 1;
01360                 child_fatal = 1;
01361                 return;
01362             }
01363             /* non-fatal death... note that it's gone in the scoreboard. */
01364             child_slot = find_child_by_pid(&pid);
01365             if (child_slot >= 0) {
01366                 for (i = 0; i < ap_threads_per_child; i++)
01367                     ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD, 
01368                                                         (request_rec *) NULL);
01369                 
01370                 ap_scoreboard_image->parent[child_slot].pid = 0;
01371                 ap_scoreboard_image->parent[child_slot].quiescing = 0;
01372                 if (processed_status == APEXIT_CHILDSICK) {
01373                     /* resource shortage, minimize the fork rate */
01374                     idle_spawn_rate = 1;
01375                 }
01376                 else if (remaining_children_to_start
01377                     && child_slot < ap_daemons_limit) {
01378                     /* we're still doing a 1-for-1 replacement of dead
01379                      * children with new children
01380                      */
01381                     make_child(ap_server_conf, child_slot);
01382                     --remaining_children_to_start;
01383                 }
01384 #if APR_HAS_OTHER_CHILD
01385             }
01386             else if (apr_proc_other_child_read(&pid, status) == 0) {
01387                 /* handled */
01388 #endif
01389             }
01390             else if (is_graceful) {
01391                 /* Great, we've probably just lost a slot in the
01392                  * scoreboard.  Somehow we don't know about this child.
01393                  */
01394                 ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
01395                              ap_server_conf,
01396                              "long lost child came home! (pid %ld)",
01397                              (long)pid.pid);
01398             }
01399             /* Don't perform idle maintenance when a child dies,
01400              * only do it when there's a timeout.  Remember only a
01401              * finite number of children can die, and it's pretty
01402              * pathological for a lot to die suddenly.
01403              */
01404             continue;
01405         }
01406         else if (remaining_children_to_start) {
01407             /* we hit a 1 second timeout in which none of the previous
01408              * generation of children needed to be reaped... so assume
01409              * they're all done, and pick up the slack if any is left.
01410              */
01411             startup_children(remaining_children_to_start);
01412             remaining_children_to_start = 0;
01413             /* In any event we really shouldn't do the code below because
01414              * few of the servers we just started are in the IDLE state
01415              * yet, so we'd mistakenly create an extra server.
01416              */
01417             continue;
01418         }
01419 
01420         perform_idle_server_maintenance();
01421     }
01422 }
01423 
01424 int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
01425 {
01426     int remaining_children_to_start;
01427     apr_status_t rv;
01428 
01429     ap_log_pid(pconf, ap_pid_fname);
01430 
01431     first_server_limit = server_limit;
01432     first_thread_limit = thread_limit;
01433     if (changed_limit_at_restart) {
01434         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
01435                      "WARNING: Attempt to change ServerLimit or ThreadLimit "
01436                      "ignored during restart");
01437         changed_limit_at_restart = 0;
01438     }
01439     
01440     /* Initialize cross-process accept lock */
01441     ap_lock_fname = apr_psprintf(_pconf, "%s.%" APR_PID_T_FMT,
01442                                  ap_server_root_relative(_pconf, ap_lock_fname),
01443