bottleneck testcase based on rubbos
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / server / mpm / experimental / leader / leader.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "apr.h"
18 #include "apr_portable.h"
19 #include "apr_strings.h"
20 #include "apr_file_io.h"
21 #include "apr_thread_proc.h"
22 #include "apr_signal.h"
23 #include "apr_thread_cond.h"
24 #include "apr_thread_mutex.h"
25 #include "apr_proc_mutex.h"
26 #define APR_WANT_STRFUNC
27 #include "apr_want.h"
28
29 #if APR_HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32 #if APR_HAVE_SYS_SOCKET_H
33 #include <sys/socket.h>
34 #endif
35 #if APR_HAVE_SYS_WAIT_H
36 #include <sys/wait.h> 
37 #endif
38 #ifdef HAVE_SYS_PROCESSOR_H
39 #include <sys/processor.h> /* for bindprocessor() */
40 #endif
41
42 #if !APR_HAS_THREADS
43 #error The Leader/Follower MPM requires APR threads, but they are unavailable.
44 #endif
45
46 #define CORE_PRIVATE 
47  
48 #include "ap_config.h"
49 #include "httpd.h" 
50 #include "http_main.h" 
51 #include "http_log.h" 
52 #include "http_config.h"        /* for read_config */ 
53 #include "http_core.h"          /* for get_remote_host */ 
54 #include "http_connection.h"
55 #include "ap_mpm.h"
56 #include "mpm_common.h"
57 #include "ap_listen.h"
58 #include "scoreboard.h" 
59 #include "mpm_default.h"
60 #include "apr_poll.h"
61
62 #include <signal.h>
63 #include <limits.h>             /* for INT_MAX */
64
65 #include "apr_atomic.h"
66
67 /* Limit on the total --- clients will be locked out if more servers than
68  * this are needed.  It is intended solely to keep the server from crashing
69  * when things get out of hand.
70  *
71  * We keep a hard maximum number of servers, for two reasons --- first off,
72  * in case something goes seriously wrong, we want to stop the fork bomb
73  * short of actually crashing the machine we're running on by filling some
74  * kernel table.  Secondly, it keeps the size of the scoreboard file small
75  * enough that we can read the whole thing without worrying too much about
76  * the overhead.
77  */
78 #ifndef DEFAULT_SERVER_LIMIT
79 #define DEFAULT_SERVER_LIMIT 16
80 #endif
81
82 /* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT.  We want
83  * some sort of compile-time limit to help catch typos.
84  */
85 #ifndef MAX_SERVER_LIMIT
86 #define MAX_SERVER_LIMIT 20000
87 #endif
88
89 /* Limit on the threads per process.  Clients will be locked out if more than
90  * this  * server_limit are needed.
91  *
92  * We keep this for one reason it keeps the size of the scoreboard file small
93  * enough that we can read the whole thing without worrying too much about
94  * the overhead.
95  */
96 #ifndef DEFAULT_THREAD_LIMIT
97 #define DEFAULT_THREAD_LIMIT 64 
98 #endif
99
100 /* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT.  We want
101  * some sort of compile-time limit to help catch typos.
102  */
103 #ifndef MAX_THREAD_LIMIT
104 #define MAX_THREAD_LIMIT 20000
105 #endif
106
107 /*
108  * Actual definitions of config globals
109  */
110
111 int ap_threads_per_child = 0;         /* Worker threads per child */
112 static int ap_daemons_to_start = 0;
113 static int min_spare_threads = 0;
114 static int max_spare_threads = 0;
115 static int ap_daemons_limit = 0;
116 static int server_limit = DEFAULT_SERVER_LIMIT;
117 static int first_server_limit;
118 static int thread_limit = DEFAULT_THREAD_LIMIT;
119 static int first_thread_limit;
120 static int changed_limit_at_restart;
121 static int dying = 0;
122 static int workers_may_exit = 0;
123 static int start_thread_may_exit = 0;
124 static int requests_this_child;
125 static int num_listensocks = 0;
126 static int resource_shortage = 0;
127 static int mpm_state = AP_MPMQ_STARTING;
128
129 typedef struct worker_wakeup_info worker_wakeup_info;
130
131 /* The structure used to pass unique initialization info to each thread */
132 typedef struct {
133     int pid;
134     int tid;
135     int sd;
136 } proc_info;
137
138
139 /* Structure used to pass information to the thread responsible for 
140  * creating the rest of the threads.
141  */
142 typedef struct {
143     apr_thread_t **threads;
144     int child_num_arg;
145     apr_threadattr_t *threadattr;
146 } thread_starter;
147
148 #define ID_FROM_CHILD_THREAD(c, t)    ((c * thread_limit) + t)
149
150 /*
151  * The max child slot ever assigned, preserved across restarts.  Necessary
152  * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts.  We 
153  * use this value to optimize routines that have to scan the entire 
154  * scoreboard.
155  */
156 int ap_max_daemons_limit = -1;
157
158 static ap_pod_t *pod;
159
160 /* *Non*-shared http_main globals... */
161
162 server_rec *ap_server_conf;
163
164 /* This MPM respects a couple of runtime flags that can aid in debugging.
165  *  Setting the -DNO_DETACH flag will prevent the root process from
166  *  detaching from its controlling terminal. Additionally, setting
167  * the -DONE_PROCESS flag (which implies -DNO_DETACH) will get you the
168  * child_main loop running in the process which originally started up.
169  * This gives you a pretty nice debugging environment.  (You'll get a SIGHUP
170  * early in standalone_main; just continue through.  This is the server
171  * trying to kill off any child processes which it might have lying
172  * around --- Apache doesn't keep track of their pids, it just sends
173  * SIGHUP to the process group, ignoring it in the root process.
174  * Continue through and you'll be fine.).
175  */
176
177 static int one_process = 0;
178
179 #ifdef DEBUG_SIGSTOP
180 int raise_sigstop_flags;
181 #endif
182
183 static apr_pool_t *pconf;                 /* Pool for config stuff */
184 static apr_pool_t *pchild;                /* Pool for httpd child stuff */
185
186 static pid_t ap_my_pid; /* Linux getpid() doesn't work except in main 
187                            thread. Use this instead */
188 static pid_t parent_pid;
189
190 /* Locks for accept serialization */
191 static apr_proc_mutex_t *accept_mutex;
192
193 #ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
194 #define SAFE_ACCEPT(stmt) (ap_listeners->next ? (stmt) : APR_SUCCESS)
195 #else
196 #define SAFE_ACCEPT(stmt) (stmt)
197 #endif
198
199
200 /* Structure used to wake up an idle worker thread
201  */
202 struct worker_wakeup_info {
203     apr_uint32_t next; /* index into worker_wakeups array,
204                         * used to build a linked list
205                         */
206     apr_thread_cond_t *cond;
207     apr_thread_mutex_t *mutex;
208 };
209
210 static worker_wakeup_info *worker_wakeup_create(apr_pool_t *pool)
211 {
212     apr_status_t rv;
213     worker_wakeup_info *wakeup;
214
215     wakeup = (worker_wakeup_info *)apr_palloc(pool, sizeof(*wakeup));
216     if ((rv = apr_thread_cond_create(&wakeup->cond, pool)) != APR_SUCCESS) {
217         return NULL;
218     }
219     if ((rv = apr_thread_mutex_create(&wakeup->mutex, APR_THREAD_MUTEX_DEFAULT,
220                                       pool)) != APR_SUCCESS) {
221         return NULL;
222     }
223     /* The wakeup's mutex will be unlocked automatically when
224      * the worker blocks on the condition variable
225      */
226     apr_thread_mutex_lock(wakeup->mutex);
227     return wakeup;
228 }
229
230
231 /* Structure used to hold a stack of idle worker threads 
232  */
233 typedef struct {
234     /* 'state' consists of several fields concatenated into a
235      * single 32-bit int for use with the apr_atomic_cas() API:
236      *   state & STACK_FIRST  is the thread ID of the first thread
237      *                        in a linked list of idle threads
238      *   state & STACK_TERMINATED  indicates whether the proc is shutting down
239      *   state & STACK_NO_LISTENER indicates whether the process has
240      *                             no current listener thread
241      */
242     apr_uint32_t state;
243 } worker_stack;
244
245 #define STACK_FIRST  0xffff
246 #define STACK_LIST_END  0xffff
247 #define STACK_TERMINATED 0x10000
248 #define STACK_NO_LISTENER 0x20000
249
250 static worker_wakeup_info **worker_wakeups = NULL;
251
252 static worker_stack* worker_stack_create(apr_pool_t *pool, apr_size_t max)
253 {
254     worker_stack *stack = (worker_stack *)apr_palloc(pool, sizeof(*stack));
255     stack->state = STACK_NO_LISTENER | STACK_LIST_END;
256     return stack;
257 }
258
259 static apr_status_t worker_stack_wait(worker_stack *stack,
260                                       apr_uint32_t worker_id)
261 {
262     worker_wakeup_info *wakeup = worker_wakeups[worker_id];
263
264     while (1) {
265         apr_uint32_t state = stack->state;
266         if (state & (STACK_TERMINATED | STACK_NO_LISTENER)) {
267             if (state & STACK_TERMINATED) {
268                 return APR_EINVAL;
269             }
270             if (apr_atomic_cas(&(stack->state), STACK_LIST_END, state) !=
271                 state) {
272                 continue;
273             }
274             else {
275                 return APR_SUCCESS;
276             }
277         }
278         wakeup->next = state;
279         if (apr_atomic_cas(&(stack->state), worker_id, state) != state) {
280             continue;
281         }
282         else {
283             return apr_thread_cond_wait(wakeup->cond, wakeup->mutex);
284         }
285     }    
286 }
287
288 static apr_status_t worker_stack_awaken_next(worker_stack *stack)
289 {
290
291     while (1) {
292         apr_uint32_t state = stack->state;
293         apr_uint32_t first = state & STACK_FIRST;
294         if (first == STACK_LIST_END) {
295             if (apr_atomic_cas(&(stack->state), state | STACK_NO_LISTENER,
296                                state) != state) {
297                 continue;
298             }
299             else {
300                 return APR_SUCCESS;
301             }
302         }
303         else {
304             worker_wakeup_info *wakeup = worker_wakeups[first];
305             if (apr_atomic_cas(&(stack->state), (state ^ first) | wakeup->next,
306                                state) != state) {
307                 continue;
308             }
309             else {
310                 /* Acquire and release the idle worker's mutex to ensure
311                  * that it's actually waiting on its condition variable
312                  */
313                 apr_status_t rv;
314                 if ((rv = apr_thread_mutex_lock(wakeup->mutex)) !=
315                     APR_SUCCESS) {
316                     return rv;
317                 }
318                 if ((rv = apr_thread_mutex_unlock(wakeup->mutex)) !=
319                     APR_SUCCESS) {
320                     return rv;
321                 }
322                 return apr_thread_cond_signal(wakeup->cond);
323             }
324         }
325     }
326 }
327
328 static apr_status_t worker_stack_term(worker_stack *stack)
329 {
330     int i;
331     apr_status_t rv;
332
333     while (1) {
334         apr_uint32_t state = stack->state;
335         if (apr_atomic_cas(&(stack->state), state | STACK_TERMINATED,
336                            state) == state) {
337             break;
338         }
339     }
340     for (i = 0; i < ap_threads_per_child; i++) {
341         if ((rv = worker_stack_awaken_next(stack)) != APR_SUCCESS) {
342             return rv;
343         }
344     }
345     return APR_SUCCESS;
346 }
347
348 static worker_stack *idle_worker_stack;
349
350 #define ST_INIT              0
351 #define ST_GRACEFUL          1
352 #define ST_UNGRACEFUL        2
353
354 static int terminate_mode = ST_INIT;
355
356 static void signal_threads(int mode)
357 {
358     if (terminate_mode == mode) {
359         return;
360     }
361     terminate_mode = mode;
362     mpm_state = AP_MPMQ_STOPPING;
363     workers_may_exit = 1;
364
365     worker_stack_term(idle_worker_stack);
366 }
367
368 AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
369 {
370     switch(query_code){
371         case AP_MPMQ_MAX_DAEMON_USED:
372             *result = ap_max_daemons_limit;
373             return APR_SUCCESS;
374         case AP_MPMQ_IS_THREADED:
375             *result = AP_MPMQ_STATIC;
376             return APR_SUCCESS;
377         case AP_MPMQ_IS_FORKED:
378             *result = AP_MPMQ_DYNAMIC;
379             return APR_SUCCESS;
380         case AP_MPMQ_HARD_LIMIT_DAEMONS:
381             *result = server_limit;
382             return APR_SUCCESS;
383         case AP_MPMQ_HARD_LIMIT_THREADS:
384             *result = thread_limit;
385             return APR_SUCCESS;
386         case AP_MPMQ_MAX_THREADS:
387             *result = ap_threads_per_child;
388             return APR_SUCCESS;
389         case AP_MPMQ_MIN_SPARE_DAEMONS:
390             *result = 0;
391             return APR_SUCCESS;
392         case AP_MPMQ_MIN_SPARE_THREADS:    
393             *result = min_spare_threads;
394             return APR_SUCCESS;
395         case AP_MPMQ_MAX_SPARE_DAEMONS:
396             *result = 0;
397             return APR_SUCCESS;
398         case AP_MPMQ_MAX_SPARE_THREADS:
399             *result = max_spare_threads;
400             return APR_SUCCESS;
401         case AP_MPMQ_MAX_REQUESTS_DAEMON:
402             *result = ap_max_requests_per_child;
403             return APR_SUCCESS;
404         case AP_MPMQ_MAX_DAEMONS:
405             *result = ap_daemons_limit;
406             return APR_SUCCESS;
407         case AP_MPMQ_MPM_STATE:
408             *result = mpm_state;
409             return APR_SUCCESS;
410     }
411     return APR_ENOTIMPL;
412 }
413
414 /* a clean exit from a child with proper cleanup */ 
415 static void clean_child_exit(int code) __attribute__ ((noreturn));
416 static void clean_child_exit(int code)
417 {
418     mpm_state = AP_MPMQ_STOPPING;
419     if (pchild) {
420         apr_pool_destroy(pchild);
421     }
422     ap_mpm_pod_close(pod);
423     exit(code);
424 }
425
426 static void just_die(int sig)
427 {
428     clean_child_exit(0);
429 }
430
431 /*****************************************************************
432  * Connection structures and accounting...
433  */
434
435 /* volatile just in case */
436 static int volatile shutdown_pending;
437 static int volatile restart_pending;
438 static int volatile is_graceful;
439 static volatile int child_fatal;
440 ap_generation_t volatile ap_my_generation;
441
442 /*
443  * ap_start_shutdown() and ap_start_restart(), below, are a first stab at
444  * functions to initiate shutdown or restart without relying on signals. 
445  * Previously this was initiated in sig_term() and restart() signal handlers, 
446  * but we want to be able to start a shutdown/restart from other sources --
447  * e.g. on Win32, from the service manager. Now the service manager can
448  * call ap_start_shutdown() or ap_start_restart() as appropiate.  Note that
449  * these functions can also be called by the child processes, since global
450  * variables are no longer used to pass on the required action to the parent.
451  *
452  * These should only be called from the parent process itself, since the
453  * parent process will use the shutdown_pending and restart_pending variables
454  * to determine whether to shutdown or restart. The child process should
455  * call signal_parent() directly to tell the parent to die -- this will
456  * cause neither of those variable to be set, which the parent will
457  * assume means something serious is wrong (which it will be, for the
458  * child to force an exit) and so do an exit anyway.
459  */
460
461 static void ap_start_shutdown(void)
462 {
463     mpm_state = AP_MPMQ_STOPPING;
464     if (shutdown_pending == 1) {
465         /* Um, is this _probably_ not an error, if the user has
466          * tried to do a shutdown twice quickly, so we won't
467          * worry about reporting it.
468          */
469         return;
470     }
471     shutdown_pending = 1;
472 }
473
474 /* do a graceful restart if graceful == 1 */
475 static void ap_start_restart(int graceful)
476 {
477     mpm_state = AP_MPMQ_STOPPING;
478     if (restart_pending == 1) {
479         /* Probably not an error - don't bother reporting it */
480         return;
481     }
482     restart_pending = 1;
483     is_graceful = graceful;
484 }
485
486 static void sig_term(int sig)
487 {
488     if (ap_my_pid == parent_pid) {
489         ap_start_shutdown();
490     }
491     else {
492         signal_threads(ST_GRACEFUL);
493     }
494 }
495
496 static void restart(int sig)
497 {
498     ap_start_restart(sig == AP_SIG_GRACEFUL);
499 }
500
501 static void set_signals(void)
502 {
503 #ifndef NO_USE_SIGACTION
504     struct sigaction sa;
505 #endif
506
507     if (!one_process) {
508         ap_fatal_signal_setup(ap_server_conf, pconf);
509     }
510
511 #ifndef NO_USE_SIGACTION
512     sigemptyset(&sa.sa_mask);
513     sa.sa_flags = 0;
514
515     sa.sa_handler = sig_term;
516     if (sigaction(SIGTERM, &sa, NULL) < 0)
517         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, 
518                      "sigaction(SIGTERM)");
519 #ifdef SIGINT
520     if (sigaction(SIGINT, &sa, NULL) < 0)
521         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, 
522                      "sigaction(SIGINT)");
523 #endif
524 #ifdef SIGXCPU
525     sa.sa_handler = SIG_DFL;
526     if (sigaction(SIGXCPU, &sa, NULL) < 0)
527         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, 
528                      "sigaction(SIGXCPU)");
529 #endif
530 #ifdef SIGXFSZ
531     sa.sa_handler = SIG_DFL;
532     if (sigaction(SIGXFSZ, &sa, NULL) < 0)
533         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, 
534                      "sigaction(SIGXFSZ)");
535 #endif
536 #ifdef SIGPIPE
537     sa.sa_handler = SIG_IGN;
538     if (sigaction(SIGPIPE, &sa, NULL) < 0)
539         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, 
540                      "sigaction(SIGPIPE)");
541 #endif
542
543     /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy 
544      * processing one */
545     sigaddset(&sa.sa_mask, SIGHUP);
546     sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL);
547     sa.sa_handler = restart;
548     if (sigaction(SIGHUP, &sa, NULL) < 0)
549         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, 
550                      "sigaction(SIGHUP)");
551     if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0)
552         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, 
553                      "sigaction(" AP_SIG_GRACEFUL_STRING ")");
554 #else
555     if (!one_process) {
556 #ifdef SIGXCPU
557         apr_signal(SIGXCPU, SIG_DFL);
558 #endif /* SIGXCPU */
559 #ifdef SIGXFSZ
560         apr_signal(SIGXFSZ, SIG_DFL);
561 #endif /* SIGXFSZ */
562     }
563
564     apr_signal(SIGTERM, sig_term);
565 #ifdef SIGHUP
566     apr_signal(SIGHUP, restart);
567 #endif /* SIGHUP */
568 #ifdef AP_SIG_GRACEFUL
569     apr_signal(AP_SIG_GRACEFUL, restart);
570 #endif /* AP_SIG_GRACEFUL */
571 #ifdef SIGPIPE
572     apr_signal(SIGPIPE, SIG_IGN);
573 #endif /* SIGPIPE */
574
575 #endif
576 }
577
578 /*****************************************************************
579  * Here follows a long bunch of generic server bookkeeping stuff...
580  */
581
582 int ap_graceful_stop_signalled(void)
583     /* XXX this is really a bad confusing obsolete name
584      * maybe it should be ap_mpm_process_exiting?
585      */
586 {
587     return workers_may_exit;
588 }
589
590 /*****************************************************************
591  * Child process main loop.
592  */
593
594 static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num,
595                            int my_thread_num, apr_bucket_alloc_t *bucket_alloc)
596 {
597     conn_rec *current_conn;
598     long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num);
599     int csd;
600     ap_sb_handle_t *sbh;
601
602     ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num);
603     apr_os_sock_get(&csd, sock);
604
605     current_conn = ap_run_create_connection(p, ap_server_conf, sock,
606                                             conn_id, sbh, bucket_alloc);
607     if (current_conn) {
608         ap_process_connection(current_conn, sock);
609         ap_lingering_close(current_conn);
610     }
611 }
612
613 /* requests_this_child has gone to zero or below.  See if the admin coded
614    "MaxRequestsPerChild 0", and keep going in that case.  Doing it this way
615    simplifies the hot path in worker_thread */
616 static void check_infinite_requests(void)
617 {
618     if (ap_max_requests_per_child) {
619         signal_threads(ST_GRACEFUL);
620     }
621     else {
622         /* wow! if you're executing this code, you may have set a record.
623          * either this child process has served over 2 billion requests, or
624          * you're running a threaded 2.0 on a 16 bit machine.  
625          *
626          * I'll buy pizza and beers at Apachecon for the first person to do
627          * the former without cheating (dorking with INT_MAX, or running with
628          * uncommitted performance patches, for example).    
629          *
630          * for the latter case, you probably deserve a beer too.   Greg Ames
631          */
632             
633         requests_this_child = INT_MAX;      /* keep going */ 
634     }
635 }
636
637 static void unblock_signal(int sig)
638 {
639     sigset_t sig_mask;
640
641     sigemptyset(&sig_mask);
642     sigaddset(&sig_mask, sig);
643 #if defined(SIGPROCMASK_SETS_THREAD_MASK)
644     sigprocmask(SIG_UNBLOCK, &sig_mask, NULL);
645 #else
646     pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL);
647 #endif
648 }
649
650 static void *worker_thread(apr_thread_t *thd, void * dummy)
651 {
652     proc_info * ti = dummy;
653     int process_slot = ti->pid;
654     int thread_slot = ti->tid;
655     apr_uint32_t my_worker_num = (apr_uint32_t)(ti->tid);
656     apr_pool_t *tpool = apr_thread_pool_get(thd);
657     void *csd = NULL;
658     apr_allocator_t *allocator;
659     apr_pool_t *ptrans;                /* Pool for per-transaction stuff */
660     apr_bucket_alloc_t *bucket_alloc;
661     int n;
662     apr_pollfd_t *pollset;
663     apr_status_t rv;
664     ap_listen_rec *lr, *last_lr = ap_listeners;
665     int is_listener;
666
667     ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL);
668
669     free(ti);
670
671     apr_allocator_create(&allocator);
672     apr_allocator_max_free_set(allocator, ap_max_mem_free);
673     /* XXX: why is ptrans's parent not tpool?  --jcw 08/2003 */
674     apr_pool_create_ex(&ptrans, NULL, NULL, allocator);
675     apr_allocator_owner_set(allocator, ptrans);
676     bucket_alloc = apr_bucket_alloc_create_ex(allocator);
677
678     apr_poll_setup(&pollset, num_listensocks, tpool);
679     for(lr = ap_listeners ; lr != NULL ; lr = lr->next)
680         apr_poll_socket_add(pollset, lr->sd, APR_POLLIN);
681
682     /* TODO: Switch to a system where threads reuse the results from earlier
683        poll calls - manoj */
684     is_listener = 0;
685     while (!workers_may_exit) {
686
687         ap_update_child_status_from_indexes(process_slot, thread_slot,
688                                             SERVER_READY, NULL);
689         if (!is_listener) {
690             /* Wait until it's our turn to become the listener */
691             if ((rv = worker_stack_wait(idle_worker_stack, my_worker_num)) !=
692                 APR_SUCCESS) {
693                 if (rv != APR_EINVAL) {
694                     ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
695                                  "worker_stack_wait failed. Shutting down");
696                 }
697                 break;
698             }
699             if (workers_may_exit) {
700                 break;
701             }
702             is_listener = 1;
703         }
704
705         /* TODO: requests_this_child should be synchronized - aaron */
706         if (requests_this_child <= 0) {
707             check_infinite_requests();
708         }
709         if (workers_may_exit) break;
710
711         if ((rv = SAFE_ACCEPT(apr_proc_mutex_lock(accept_mutex)))
712             != APR_SUCCESS) {
713             int level = APLOG_EMERG;
714
715             if (workers_may_exit) {
716                 break;
717             }
718             if (ap_scoreboard_image->parent[process_slot].generation != 
719                 ap_scoreboard_image->global->running_generation) {
720                 level = APLOG_DEBUG; /* common to get these at restart time */
721             }
722             ap_log_error(APLOG_MARK, level, rv, ap_server_conf,
723                          "apr_proc_mutex_lock failed. Attempting to shutdown "
724                          "process gracefully.");
725             signal_threads(ST_GRACEFUL);
726             break;                    /* skip the lock release */
727         }
728
729         if (!ap_listeners->next) {
730             /* Only one listener, so skip the poll */
731             lr = ap_listeners;
732         }
733         else {
734             while (!workers_may_exit) {
735                 apr_status_t ret;
736                 apr_int16_t event;
737
738                 ret = apr_poll(pollset, num_listensocks, &n, -1);
739                 if (ret != APR_SUCCESS) {
740                     if (APR_STATUS_IS_EINTR(ret)) {
741                         continue;
742                     }
743
744                     /* apr_poll() will only return errors in catastrophic
745                      * circumstances. Let's try exiting gracefully, for now. */
746                     ap_log_error(APLOG_MARK, APLOG_ERR, ret, (const server_rec *)
747                                  ap_server_conf, "apr_poll: (listen)");
748                     signal_threads(ST_GRACEFUL);
749                 }
750
751                 if (workers_may_exit) break;
752
753                 /* find a listener */
754                 lr = last_lr;
755                 do {
756                     lr = lr->next;
757                     if (lr == NULL) {
758                         lr = ap_listeners;
759                     }
760                     /* XXX: Should we check for POLLERR? */
761                     apr_poll_revents_get(&event, lr->sd, pollset);
762                     if (event & APR_POLLIN) {
763                         last_lr = lr;
764                         goto got_fd;
765                     }
766                 } while (lr != last_lr);
767             }
768         }
769     got_fd:
770         if (!workers_may_exit) {
771             rv = lr->accept_func(&csd, lr, ptrans);
772             /* later we trash rv and rely on csd to indicate success/failure */
773             AP_DEBUG_ASSERT(rv == APR_SUCCESS || !csd);
774
775             if (rv == APR_EGENERAL) {
776                 /* E[NM]FILE, ENOMEM, etc */
777                 resource_shortage = 1;
778                 signal_threads(ST_GRACEFUL);
779             }
780             if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex)))
781                 != APR_SUCCESS) {
782                 int level = APLOG_EMERG;
783
784                 if (workers_may_exit) {
785                     break;
786                 }
787                 if (ap_scoreboard_image->parent[process_slot].generation != 
788                     ap_scoreboard_image->global->running_generation) {
789                     level = APLOG_DEBUG; /* common to get these at restart time */
790                 }
791                 ap_log_error(APLOG_MARK, level, rv, ap_server_conf,
792                              "apr_proc_mutex_unlock failed. Attempting to "
793                              "shutdown process gracefully.");
794                 signal_threads(ST_GRACEFUL);
795             }
796             if (csd != NULL) {
797                 is_listener = 0;
798                 worker_stack_awaken_next(idle_worker_stack);
799                 process_socket(ptrans, csd, process_slot,
800                                thread_slot, bucket_alloc);
801                 apr_pool_clear(ptrans);
802                 requests_this_child--;
803             }
804             if ((ap_mpm_pod_check(pod) == APR_SUCCESS) ||
805                 (ap_my_generation !=
806                  ap_scoreboard_image->global->running_generation)) {
807                 signal_threads(ST_GRACEFUL);
808                 break;
809             }
810         }
811         else {
812             if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex)))
813                 != APR_SUCCESS) {
814                 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
815                              "apr_proc_mutex_unlock failed. Attempting to "
816                              "shutdown process gracefully.");
817                 signal_threads(ST_GRACEFUL);
818             }
819             break;
820         }
821     }
822
823     dying = 1;
824     ap_scoreboard_image->parent[process_slot].quiescing = 1;
825
826     worker_stack_term(idle_worker_stack);
827
828     ap_update_child_status_from_indexes(process_slot, thread_slot,
829         (dying) ? SERVER_DEAD : SERVER_GRACEFUL, (request_rec *) NULL);
830
831     apr_bucket_alloc_destroy(bucket_alloc);
832
833     apr_thread_exit(thd, APR_SUCCESS);
834     return NULL;
835 }
836
837 static int check_signal(int signum)
838 {
839     switch (signum) {
840     case SIGTERM:
841     case SIGINT:
842         return 1;
843     }
844     return 0;
845 }
846
847 /* XXX under some circumstances not understood, children can get stuck
848  *     in start_threads forever trying to take over slots which will
849  *     never be cleaned up; for now there is an APLOG_DEBUG message issued
850  *     every so often when this condition occurs
851  */
852 static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy)
853 {
854     thread_starter *ts = dummy;
855     apr_thread_t **threads = ts->threads;
856     apr_threadattr_t *thread_attr = ts->threadattr;
857     int child_num_arg = ts->child_num_arg;
858     int my_child_num = child_num_arg;
859     proc_info *my_info;
860     apr_status_t rv;
861     int i;
862     int threads_created = 0;
863     int loops;
864     int prev_threads_created;
865
866     idle_worker_stack = worker_stack_create(pchild, ap_threads_per_child);
867     if (idle_worker_stack == NULL) {
868         ap_log_error(APLOG_MARK, APLOG_ALERT, 0, ap_server_conf,
869                      "worker_stack_create() failed");
870         clean_child_exit(APEXIT_CHILDFATAL);
871     }
872
873     worker_wakeups = (worker_wakeup_info **)
874         apr_palloc(pchild, sizeof(worker_wakeup_info *) *
875                    ap_threads_per_child);
876
877     loops = prev_threads_created = 0;
878     while (1) {
879         for (i = 0; i < ap_threads_per_child; i++) {
880             int status = ap_scoreboard_image->servers[child_num_arg][i].status;
881             worker_wakeup_info *wakeup;
882
883             if (status != SERVER_GRACEFUL && status != SERVER_DEAD) {
884                 continue;
885             }
886
887             wakeup = worker_wakeup_create(pchild);
888             if (wakeup == NULL) {
889                 ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, 0,
890                              ap_server_conf, "worker_wakeup_create failed");
891                 clean_child_exit(APEXIT_CHILDFATAL);
892             }
893             worker_wakeups[threads_created] = wakeup;
894             my_info = (proc_info *)malloc(sizeof(proc_info));
895             if (my_info == NULL) {
896                 ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf,
897                              "malloc: out of memory");
898                 clean_child_exit(APEXIT_CHILDFATAL);
899             }
900             my_info->pid = my_child_num;
901             my_info->tid = i;
902             my_info->sd = 0;
903         
904             /* We are creating threads right now */
905             ap_update_child_status_from_indexes(my_child_num, i,
906                                                 SERVER_STARTING, NULL);
907             /* We let each thread update its own scoreboard entry.  This is
908              * done because it lets us deal with tid better.
909              */
910             rv = apr_thread_create(&threads[i], thread_attr, 
911                                    worker_thread, my_info, pchild);
912             if (rv != APR_SUCCESS) {
913                 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
914                     "apr_thread_create: unable to create worker thread");
915                 /* In case system resources are maxxed out, we don't want
916                    Apache running away with the CPU trying to fork over and
917                    over and over again if we exit. */
918                 apr_sleep(10 * APR_USEC_PER_SEC);
919                 clean_child_exit(APEXIT_CHILDFATAL);
920             }
921             threads_created++;
922         }
923         if (start_thread_may_exit || threads_created == ap_threads_per_child) {
924             break;
925         }
926         /* wait for previous generation to clean up an entry */
927         apr_sleep(1 * APR_USEC_PER_SEC);
928         ++loops;
929         if (loops % 120 == 0) { /* every couple of minutes */
930             if (prev_threads_created == threads_created) {
931                 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
932                              "child %" APR_PID_T_FMT " isn't taking over "
933                              "slots very quickly (%d of %d)",
934                              ap_my_pid, threads_created, ap_threads_per_child);
935             }
936             prev_threads_created = threads_created;
937         }
938     }
939     
940     /* What state should this child_main process be listed as in the 
941      * scoreboard...?
942      *  ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING, 
943      *                                      (request_rec *) NULL);
944      * 
945      *  This state should be listed separately in the scoreboard, in some kind
946      *  of process_status, not mixed in with the worker threads' status.   
947      *  "life_status" is almost right, but it's in the worker's structure, and 
948      *  the name could be clearer.   gla
949      */
950     apr_thread_exit(thd, APR_SUCCESS);
951     return NULL;
952 }
953
954 static void join_workers(apr_thread_t **threads)
955 {
956     int i;
957     apr_status_t rv, thread_rv;
958
959     for (i = 0; i < ap_threads_per_child; i++) {
960         if (threads[i]) { /* if we ever created this thread */
961             rv = apr_thread_join(&thread_rv, threads[i]);
962             if (rv != APR_SUCCESS) {
963                 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
964                              "apr_thread_join: unable to join worker "
965                              "thread %d",
966                              i);
967             }
968         }
969     }
970 }
971
972 static void join_start_thread(apr_thread_t *start_thread_id)
973 {
974     apr_status_t rv, thread_rv;
975
976     start_thread_may_exit = 1; /* tell it to give up in case it is still 
977                                 * trying to take over slots from a 
978                                 * previous generation
979                                 */
980     rv = apr_thread_join(&thread_rv, start_thread_id);
981     if (rv != APR_SUCCESS) {
982         ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
983                      "apr_thread_join: unable to join the start "
984                      "thread");
985     }
986 }
987
988 static void child_main(int child_num_arg)
989 {
990     apr_thread_t **threads;
991     apr_status_t rv;
992     thread_starter *ts;
993     apr_threadattr_t *thread_attr;
994     apr_thread_t *start_thread_id;
995
996     mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
997                                   * child initializes
998                                   */
999
1000     ap_my_pid = getpid();
1001     ap_fatal_signal_child_setup(ap_server_conf);
1002     apr_pool_create(&pchild, pconf);
1003
1004     /*stuff to do before we switch id's, so we have permissions.*/
1005     ap_reopen_scoreboard(pchild, NULL, 0);
1006
1007     rv = SAFE_ACCEPT(apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname,
1008                                                pchild));
1009     if (rv != APR_SUCCESS) {
1010         ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
1011                      "Couldn't initialize cross-process lock in child");
1012         clean_child_exit(APEXIT_CHILDFATAL);
1013     }
1014
1015     if (unixd_setup_child()) {
1016         clean_child_exit(APEXIT_CHILDFATAL);
1017     }
1018
1019     ap_run_child_init(pchild, ap_server_conf);
1020
1021     /* done with init critical section */
1022
1023     /* Just use the standard apr_setup_signal_thread to block all signals
1024      * from being received.  The child processes no longer use signals for
1025      * any communication with the parent process.
1026      */
1027     rv = apr_setup_signal_thread();
1028     if (rv != APR_SUCCESS) {
1029         ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
1030                      "Couldn't initialize signal thread");
1031         clean_child_exit(APEXIT_CHILDFATAL);
1032     }
1033
1034     if (ap_max_requests_per_child) {
1035         requests_this_child = ap_max_requests_per_child;
1036     }
1037     else {
1038         /* coding a value of zero means infinity */
1039         requests_this_child = INT_MAX;
1040     }
1041     
1042     /* Setup worker threads */
1043
1044     /* clear the storage; we may not create all our threads immediately, 
1045      * and we want a 0 entry to indicate a thread which was not created
1046      */
1047     threads = (apr_thread_t **)calloc(1, 
1048                                 sizeof(apr_thread_t *) * ap_threads_per_child);
1049     if (threads == NULL) {
1050         ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf,
1051                      "malloc: out of memory");
1052         clean_child_exit(APEXIT_CHILDFATAL);
1053     }
1054
1055     ts = (thread_starter *)apr_palloc(pchild, sizeof(*ts));
1056
1057     apr_threadattr_create(&thread_attr, pchild);
1058     /* 0 means PTHREAD_CREATE_JOINABLE */
1059     apr_threadattr_detach_set(thread_attr, 0);
1060
1061     ts->threads = threads;
1062     ts->child_num_arg = child_num_arg;
1063     ts->threadattr = thread_attr;
1064
1065     rv = apr_thread_create(&start_thread_id, thread_attr, start_threads,
1066                            ts, pchild);
1067     if (rv != APR_SUCCESS) {
1068         ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1069                      "apr_thread_create: unable to create worker thread");
1070         /* In case system resources are maxxed out, we don't want
1071            Apache running away with the CPU trying to fork over and
1072            over and over again if we exit. */
1073         apr_sleep(10 * APR_USEC_PER_SEC);
1074         clean_child_exit(APEXIT_CHILDFATAL);
1075     }
1076
1077     mpm_state = AP_MPMQ_RUNNING;
1078
1079     /* If we are only running in one_process mode, we will want to
1080      * still handle signals. */
1081     if (one_process) {
1082         /* Block until we get a terminating signal. */
1083         apr_signal_thread(check_signal);
1084         /* make sure the start thread has finished; signal_threads() 
1085          * and join_workers() depend on that
1086          */
1087         /* XXX join_start_thread() won't be awakened if one of our
1088          *     threads encounters a critical error and attempts to
1089          *     shutdown this child
1090          */
1091         join_start_thread(start_thread_id);
1092         signal_threads(ST_UNGRACEFUL); /* helps us terminate a little more
1093                            * quickly than the dispatch of the signal thread
1094                            * beats the Pipe of Death and the browsers
1095                            */
1096         /* A terminating signal was received. Now join each of the
1097          * workers to clean them up.
1098          *   If the worker already exited, then the join frees
1099          *   their resources and returns.
1100          *   If the worker hasn't exited, then this blocks until
1101          *   they have (then cleans up).
1102          */
1103         join_workers(threads);
1104     }
1105     else { /* !one_process */
1106         /* remove SIGTERM from the set of blocked signals...  if one of
1107          * the other threads in the process needs to take us down
1108          * (e.g., for MaxRequestsPerChild) it will send us SIGTERM
1109          */
1110         unblock_signal(SIGTERM);
1111         join_start_thread(start_thread_id);
1112         join_workers(threads);
1113     }
1114
1115     free(threads);
1116
1117     clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0);
1118 }
1119
1120 static int make_child(server_rec *s, int slot) 
1121 {
1122     int pid;
1123
1124     if (slot + 1 > ap_max_daemons_limit) {
1125         ap_max_daemons_limit = slot + 1;
1126     }
1127
1128     if (one_process) {
1129         set_signals();
1130         ap_scoreboard_image->parent[slot].pid = getpid();
1131         child_main(slot);
1132     }
1133
1134     if ((pid = fork()) == -1) {
1135         ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, 
1136                      "fork: Unable to fork new process");
1137
1138         /* fork didn't succeed. Fix the scoreboard or else
1139          * it will say SERVER_STARTING forever and ever
1140          */
1141         ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, NULL);
1142
1143         /* In case system resources are maxxed out, we don't want
1144            Apache running away with the CPU trying to fork over and
1145            over and over again. */
1146         apr_sleep(10 * APR_USEC_PER_SEC);
1147
1148         return -1;
1149     }
1150
1151     if (!pid) {
1152 #ifdef HAVE_BINDPROCESSOR
1153         /* By default, AIX binds to a single processor.  This bit unbinds
1154          * children which will then bind to another CPU.
1155          */
1156         int status = bindprocessor(BINDPROCESS, (int)getpid(),
1157                                PROCESSOR_CLASS_ANY);
1158         if (status != OK)
1159             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, 
1160                          ap_server_conf,
1161                          "processor unbind failed %d", status);
1162 #endif
1163         RAISE_SIGSTOP(MAKE_CHILD);
1164
1165         apr_signal(SIGTERM, just_die);
1166         child_main(slot);
1167
1168         clean_child_exit(0);
1169     }
1170     /* else */
1171     ap_scoreboard_image->parent[slot].quiescing = 0;
1172     ap_scoreboard_image->parent[slot].pid = pid;
1173     return 0;
1174 }
1175
1176 /* start up a bunch of children */
1177 static void startup_children(int number_to_start)
1178 {
1179     int i;
1180
1181     for (i = 0; number_to_start && i < ap_daemons_limit; ++i) {
1182         if (ap_scoreboard_image->parent[i].pid != 0) {
1183             continue;
1184         }
1185         if (make_child(ap_server_conf, i) < 0) {
1186             break;
1187         }
1188         --number_to_start;
1189     }
1190 }
1191
1192
1193 /*
1194  * idle_spawn_rate is the number of children that will be spawned on the
1195  * next maintenance cycle if there aren't enough idle servers.  It is
1196  * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
1197  * without the need to spawn.
1198  */
1199 static int idle_spawn_rate = 1;
1200 #ifndef MAX_SPAWN_RATE
1201 #define MAX_SPAWN_RATE        (32)
1202 #endif
1203 static int hold_off_on_exponential_spawning;
1204
1205 static void perform_idle_server_maintenance(void)
1206 {
1207     int i, j;
1208     int idle_thread_count;
1209     worker_score *ws;
1210     process_score *ps;
1211     int free_length;
1212     int totally_free_length = 0;
1213     int free_slots[MAX_SPAWN_RATE];
1214     int last_non_dead;
1215     int total_non_dead;
1216
1217     /* initialize the free_list */
1218     free_length = 0;
1219
1220     idle_thread_count = 0;
1221     last_non_dead = -1;
1222     total_non_dead = 0;
1223
1224     for (i = 0; i < ap_daemons_limit; ++i) {
1225         /* Initialization to satisfy the compiler. It doesn't know
1226          * that ap_threads_per_child is always > 0 */
1227         int status = SERVER_DEAD;
1228         int any_dying_threads = 0;
1229         int any_dead_threads = 0;
1230         int all_dead_threads = 1;
1231
1232         if (i >= ap_max_daemons_limit && totally_free_length == idle_spawn_rate)
1233             break;
1234         ps = &ap_scoreboard_image->parent[i];
1235         for (j = 0; j < ap_threads_per_child; j++) {
1236             ws = &ap_scoreboard_image->servers[i][j];
1237             status = ws->status;
1238
1239             /* XXX any_dying_threads is probably no longer needed    GLA */
1240             any_dying_threads = any_dying_threads || 
1241                                 (status == SERVER_GRACEFUL);
1242             any_dead_threads = any_dead_threads || (status == SERVER_DEAD);
1243             all_dead_threads = all_dead_threads &&
1244                                    (status == SERVER_DEAD ||
1245                                     status == SERVER_GRACEFUL);
1246
1247             /* We consider a starting server as idle because we started it
1248              * at least a cycle ago, and if it still hasn't finished starting
1249              * then we're just going to swamp things worse by forking more.
1250              * So we hopefully won't need to fork more if we count it.
1251              * This depends on the ordering of SERVER_READY and SERVER_STARTING.
1252              */
1253             if (status <= SERVER_READY && status != SERVER_DEAD &&
1254                     !ps->quiescing &&
1255                     ps->generation == ap_my_generation &&
1256                  /* XXX the following shouldn't be necessary if we clean up 
1257                   *     properly after seg faults, but we're not yet    GLA 
1258                   */     
1259                     ps->pid != 0) {
1260                 ++idle_thread_count;
1261             }
1262         }
1263         if (any_dead_threads && totally_free_length < idle_spawn_rate 
1264                 && (!ps->pid               /* no process in the slot */
1265                     || ps->quiescing)) {   /* or at least one is going away */
1266             if (all_dead_threads) {
1267                 /* great! we prefer these, because the new process can
1268                  * start more threads sooner.  So prioritize this slot 
1269                  * by putting it ahead of any slots with active threads.
1270                  *
1271                  * first, make room by moving a slot that's potentially still
1272                  * in use to the end of the array
1273                  */
1274                 free_slots[free_length] = free_slots[totally_free_length];
1275                 free_slots[totally_free_length++] = i;
1276             }
1277             else {
1278                 /* slot is still in use - back of the bus
1279                  */
1280             free_slots[free_length] = i;
1281             }
1282             ++free_length;
1283         }
1284         /* XXX if (!ps->quiescing)     is probably more reliable  GLA */
1285         if (!any_dying_threads) {
1286             last_non_dead = i;
1287             ++total_non_dead;
1288         }
1289     }
1290     ap_max_daemons_limit = last_non_dead + 1;
1291
1292     if (idle_thread_count > max_spare_threads) {
1293         /* Kill off one child */
1294         ap_mpm_pod_signal(pod);
1295         idle_spawn_rate = 1;
1296     }
1297     else if (idle_thread_count < min_spare_threads) {
1298         /* terminate the free list */
1299         if (free_length == 0) {
1300             /* only report this condition once */
1301             static int reported = 0;
1302             
1303             if (!reported) {
1304                 ap_log_error(APLOG_MARK, APLOG_ERR, 0, 
1305                              ap_server_conf,
1306                              "server reached MaxClients setting, consider"
1307                              " raising the MaxClients setting");
1308                 reported = 1;
1309             }
1310             idle_spawn_rate = 1;
1311         }
1312         else {
1313             if (free_length > idle_spawn_rate) {
1314                 free_length = idle_spawn_rate;
1315             }
1316             if (idle_spawn_rate >= 8) {
1317                 ap_log_error(APLOG_MARK, APLOG_INFO, 0, 
1318                              ap_server_conf,
1319                              "server seems busy, (you may need "
1320                              "to increase StartServers, ThreadsPerChild "
1321                              "or Min/MaxSpareThreads), "
1322                              "spawning %d children, there are around %d idle "
1323                              "threads, and %d total children", free_length,
1324                              idle_thread_count, total_non_dead);
1325             }
1326             for (i = 0; i < free_length; ++i) {
1327                 make_child(ap_server_conf, free_slots[i]);
1328             }
1329             /* the next time around we want to spawn twice as many if this
1330              * wasn't good enough, but not if we've just done a graceful
1331              */
1332             if (hold_off_on_exponential_spawning) {
1333                 --hold_off_on_exponential_spawning;
1334             }
1335             else if (idle_spawn_rate < MAX_SPAWN_RATE) {
1336                 idle_spawn_rate *= 2;
1337             }
1338         }
1339     }
1340     else {
1341       idle_spawn_rate = 1;
1342     }
1343 }
1344
1345 static void server_main_loop(int remaining_children_to_start)
1346 {
1347     int child_slot;
1348     apr_exit_why_e exitwhy;
1349     int status, processed_status;
1350     apr_proc_t pid;
1351     int i;
1352
1353     while (!restart_pending && !shutdown_pending) {
1354         ap_wait_or_timeout(&exitwhy, &status, &pid, pconf);
1355         
1356         if (pid.pid != -1) {
1357             processed_status = ap_process_child_status(&pid, exitwhy, status);
1358             if (processed_status == APEXIT_CHILDFATAL) {
1359                 shutdown_pending = 1;
1360                 child_fatal = 1;
1361                 return;
1362             }
1363             /* non-fatal death... note that it's gone in the scoreboard. */
1364             child_slot = find_child_by_pid(&pid);
1365             if (child_slot >= 0) {
1366                 for (i = 0; i < ap_threads_per_child; i++)
1367                     ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD, 
1368                                                         (request_rec *) NULL);
1369                 
1370                 ap_scoreboard_image->parent[child_slot].pid = 0;
1371                 ap_scoreboard_image->parent[child_slot].quiescing = 0;
1372                 if (processed_status == APEXIT_CHILDSICK) {
1373                     /* resource shortage, minimize the fork rate */
1374                     idle_spawn_rate = 1;
1375                 }
1376                 else if (remaining_children_to_start
1377                     && child_slot < ap_daemons_limit) {
1378                     /* we're still doing a 1-for-1 replacement of dead
1379                      * children with new children
1380                      */
1381                     make_child(ap_server_conf, child_slot);
1382                     --remaining_children_to_start;
1383                 }
1384 #if APR_HAS_OTHER_CHILD
1385             }
1386             else if (apr_proc_other_child_read(&pid, status) == 0) {
1387                 /* handled */
1388 #endif
1389             }
1390             else if (is_graceful) {
1391                 /* Great, we've probably just lost a slot in the
1392                  * scoreboard.  Somehow we don't know about this child.
1393                  */
1394                 ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
1395                              ap_server_conf,
1396                              "long lost child came home! (pid %ld)",
1397                              (long)pid.pid);
1398             }
1399             /* Don't perform idle maintenance when a child dies,
1400              * only do it when there's a timeout.  Remember only a
1401              * finite number of children can die, and it's pretty
1402              * pathological for a lot to die suddenly.
1403              */
1404             continue;
1405         }
1406         else if (remaining_children_to_start) {
1407             /* we hit a 1 second timeout in which none of the previous
1408              * generation of children needed to be reaped... so assume
1409              * they're all done, and pick up the slack if any is left.
1410              */
1411             startup_children(remaining_children_to_start);
1412             remaining_children_to_start = 0;
1413             /* In any event we really shouldn't do the code below because
1414              * few of the servers we just started are in the IDLE state
1415              * yet, so we'd mistakenly create an extra server.
1416              */
1417             continue;
1418         }
1419
1420         perform_idle_server_maintenance();
1421     }
1422 }
1423
1424 int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
1425 {
1426     int remaining_children_to_start;
1427     apr_status_t rv;
1428
1429     ap_log_pid(pconf, ap_pid_fname);
1430
1431     first_server_limit = server_limit;
1432     first_thread_limit = thread_limit;
1433     if (changed_limit_at_restart) {
1434         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
1435                      "WARNING: Attempt to change ServerLimit or ThreadLimit "
1436                      "ignored during restart");
1437         changed_limit_at_restart = 0;
1438     }
1439     
1440     /* Initialize cross-process accept lock */
1441     ap_lock_fname = apr_psprintf(_pconf, "%s.%" APR_PID_T_FMT,
1442                                  ap_server_root_relative(_pconf, ap_lock_fname),
1443                                  ap_my_pid);
1444
1445     rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname, 
1446                                ap_accept_lock_mech, _pconf);
1447     if (rv != APR_SUCCESS) {
1448         ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
1449                      "Couldn't create accept lock");
1450         mpm_state = AP_MPMQ_STOPPING;
1451         return 1;
1452     }
1453
1454 #if APR_USE_SYSVSEM_SERIALIZE
1455     if (ap_accept_lock_mech == APR_LOCK_DEFAULT || 
1456         ap_accept_lock_mech == APR_LOCK_SYSVSEM) {
1457 #else
1458     if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) {
1459 #endif
1460         rv = unixd_set_proc_mutex_perms(accept_mutex);
1461         if (rv != APR_SUCCESS) {
1462             ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
1463                          "Couldn't set permissions on cross-process lock; "
1464                          "check User and Group directives");
1465             mpm_state = AP_MPMQ_STOPPING;
1466             return 1;
1467         }
1468     }
1469
1470     if (!is_graceful) {
1471         if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
1472             mpm_state = AP_MPMQ_STOPPING;
1473             return 1;
1474         }
1475         /* fix the generation number in the global score; we just got a new,
1476          * cleared scoreboard
1477          */
1478         ap_scoreboard_image->global->running_generation = ap_my_generation;
1479     }
1480
1481     set_signals();
1482     /* Don't thrash... */
1483     if (max_spare_threads < min_spare_threads + ap_threads_per_child)
1484         max_spare_threads = min_spare_threads + ap_threads_per_child;
1485
1486     /* If we're doing a graceful_restart then we're going to see a lot
1487      * of children exiting immediately when we get into the main loop
1488      * below (because we just sent them AP_SIG_GRACEFUL).  This happens pretty
1489      * rapidly... and for each one that exits we'll start a new one until
1490      * we reach at least daemons_min_free.  But we may be permitted to
1491      * start more than that, so we'll just keep track of how many we're
1492      * supposed to start up without the 1 second penalty between each fork.
1493      */
1494     remaining_children_to_start = ap_daemons_to_start;
1495     if (remaining_children_to_start > ap_daemons_limit) {
1496         remaining_children_to_start = ap_daemons_limit;
1497     }
1498     if (!is_graceful) {
1499         startup_children(remaining_children_to_start);
1500         remaining_children_to_start = 0;
1501     }
1502     else {
1503         /* give the system some time to recover before kicking into
1504             * exponential mode */
1505         hold_off_on_exponential_spawning = 10;
1506     }
1507
1508     ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
1509                 "%s configured -- resuming normal operations",
1510                 ap_get_server_version());
1511     ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
1512                 "Server built: %s", ap_get_server_built());
1513 #ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH
1514     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1515                 "AcceptMutex: %s (default: %s)",
1516                 apr_proc_mutex_name(accept_mutex),
1517                 apr_proc_mutex_defname());
1518 #endif
1519     restart_pending = shutdown_pending = 0;
1520     mpm_state = AP_MPMQ_RUNNING;
1521
1522     server_main_loop(remaining_children_to_start);
1523     mpm_state = AP_MPMQ_STOPPING;
1524
1525     if (shutdown_pending) {
1526         /* Time to gracefully shut down:
1527          * Kill child processes, tell them to call child_exit, etc...
1528          * (By "gracefully" we don't mean graceful in the same sense as 
1529          * "apachectl graceful" where we allow old connections to finish.)
1530          */
1531         if (unixd_killpg(getpgrp(), SIGTERM) < 0) {
1532             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGTERM");
1533         }
1534         ap_reclaim_child_processes(1);                /* Start with SIGTERM */
1535
1536         if (!child_fatal) {
1537             /* cleanup pid file on normal shutdown */
1538             const char *pidfile = NULL;
1539             pidfile = ap_server_root_relative (pconf, ap_pid_fname);
1540             if ( pidfile != NULL && unlink(pidfile) == 0)
1541                 ap_log_error(APLOG_MARK, APLOG_INFO, 0,
1542                              ap_server_conf,
1543                              "removed PID file %s (pid=%ld)",
1544                              pidfile, (long)getpid());
1545     
1546             ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,
1547                          ap_server_conf, "caught SIGTERM, shutting down");
1548         }
1549         return 1;
1550     }
1551
1552     /* we've been told to restart */
1553     apr_signal(SIGHUP, SIG_IGN);
1554
1555     if (one_process) {
1556         /* not worth thinking about */
1557         return 1;
1558     }
1559
1560     /* advance to the next generation */
1561     /* XXX: we really need to make sure this new generation number isn't in
1562      * use by any of the children.
1563      */
1564     ++ap_my_generation;
1565     ap_scoreboard_image->global->running_generation = ap_my_generation;
1566     
1567     if (is_graceful) {
1568         ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
1569                      AP_SIG_GRACEFUL_STRING " received.  Doing graceful restart");
1570         /* wake up the children...time to die.  But we'll have more soon */
1571         ap_mpm_pod_killpg(pod, ap_daemons_limit);
1572     
1573
1574         /* This is mostly for debugging... so that we know what is still
1575          * gracefully dealing with existing request.
1576          */
1577         
1578     }
1579     else {
1580         /* Kill 'em all.  Since the child acts the same on the parents SIGTERM 
1581          * and a SIGHUP, we may as well use the same signal, because some user
1582          * pthreads are stealing signals from us left and right.
1583          */
1584         ap_mpm_pod_killpg(pod, ap_daemons_limit);
1585
1586         ap_reclaim_child_processes(1);                /* Start with SIGTERM */
1587         ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
1588                     "SIGHUP received.  Attempting to restart");
1589     }
1590
1591     return 0;
1592 }
1593
1594 /* This really should be a post_config hook, but the error log is already
1595  * redirected by that point, so we need to do this in the open_logs phase.
1596  */
1597 static int leader_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
1598 {
1599     apr_status_t rv;
1600
1601     pconf = p;
1602     ap_server_conf = s;
1603
1604     if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {
1605         ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0,
1606                      NULL, "no listening sockets available, shutting down");
1607         return DONE;
1608     }
1609
1610     if (!one_process) {
1611         if ((rv = ap_mpm_pod_open(pconf, &pod))) {
1612             ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL,
1613                     "Could not open pipe-of-death.");
1614             return DONE;
1615         }
1616     }
1617     return OK;
1618 }
1619
1620 static int leader_pre_config(apr_pool_t *pconf, apr_pool_t *plog, 
1621                              apr_pool_t *ptemp)
1622 {
1623     static int restart_num = 0;
1624     int no_detach, debug, foreground;
1625     ap_directive_t *pdir;
1626     ap_directive_t *max_clients = NULL;
1627     apr_status_t rv;
1628
1629     mpm_state = AP_MPMQ_STARTING;
1630
1631     /* make sure that "ThreadsPerChild" gets set before "MaxClients" */
1632     for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) {
1633         if (strncasecmp(pdir->directive, "ThreadsPerChild", 15) == 0) {
1634             if (!max_clients) {
1635                 break; /* we're in the clear, got ThreadsPerChild first */
1636             }
1637             else {
1638                 /* now to swap the data */
1639                 ap_directive_t temp;
1640
1641                 temp.directive = pdir->directive;
1642                 temp.args = pdir->args;
1643                 /* Make sure you don't change 'next', or you may get loops! */
1644                 /* XXX: first_child, parent, and data can never be set
1645                  * for these directives, right? -aaron */
1646                 temp.filename = pdir->filename;
1647                 temp.line_num = pdir->line_num;
1648
1649                 pdir->directive = max_clients->directive;
1650                 pdir->args = max_clients->args;
1651                 pdir->filename = max_clients->filename;
1652                 pdir->line_num = max_clients->line_num;
1653                 
1654                 max_clients->directive = temp.directive;
1655                 max_clients->args = temp.args;
1656                 max_clients->filename = temp.filename;
1657                 max_clients->line_num = temp.line_num;
1658                 break;
1659             }
1660         }
1661         else if (!max_clients
1662                  && strncasecmp(pdir->directive, "MaxClients", 10) == 0) {
1663             max_clients = pdir;
1664         }
1665     }
1666
1667     debug = ap_exists_config_define("DEBUG");
1668
1669     if (debug) {
1670         foreground = one_process = 1;
1671         no_detach = 0;
1672     }
1673     else {
1674         one_process = ap_exists_config_define("ONE_PROCESS");
1675         no_detach = ap_exists_config_define("NO_DETACH");
1676         foreground = ap_exists_config_define("FOREGROUND");
1677     }
1678
1679     /* sigh, want this only the second time around */
1680     if (restart_num++ == 1) {
1681         is_graceful = 0;
1682
1683         if (!one_process && !foreground) {
1684             rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND
1685                                            : APR_PROC_DETACH_DAEMONIZE);
1686             if (rv != APR_SUCCESS) {
1687                 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,
1688                              "apr_proc_detach failed");
1689                 return HTTP_INTERNAL_SERVER_ERROR;
1690             }
1691         }
1692         parent_pid = ap_my_pid = getpid();
1693     }
1694
1695     unixd_pre_config(ptemp);
1696     ap_listen_pre_config();
1697     ap_daemons_to_start = DEFAULT_START_DAEMON;
1698     min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
1699     max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
1700     ap_daemons_limit = server_limit;
1701     ap_threads_per_child = DEFAULT_THREADS_PER_CHILD;
1702     ap_pid_fname = DEFAULT_PIDLOG;
1703     ap_lock_fname = DEFAULT_LOCKFILE;
1704     ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
1705     ap_extended_status = 0;
1706 #ifdef AP_MPM_WANT_SET_MAX_MEM_FREE
1707         ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED;
1708 #endif
1709
1710     apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir));
1711
1712     return OK;
1713 }
1714
1715 static void leader_hooks(apr_pool_t *p)
1716 {
1717     /* The leader open_logs phase must run before the core's, or stderr
1718      * will be redirected to a file, and the messages won't print to the
1719      * console.
1720      */
1721     static const char *const aszSucc[] = {"core.c", NULL};
1722     one_process = 0;
1723
1724     ap_hook_open_logs(leader_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE);
1725     /* we need to set the MPM state before other pre-config hooks use MPM query
1726      * to retrieve it, so register as REALLY_FIRST
1727      */
1728     ap_hook_pre_config(leader_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
1729 }
1730
1731 static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy,
1732                                         const char *arg) 
1733 {
1734     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1735     if (err != NULL) {
1736         return err;
1737     }
1738
1739     ap_daemons_to_start = atoi(arg);
1740     return NULL;
1741 }
1742
1743 static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy,
1744                                          const char *arg)
1745 {
1746     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1747     if (err != NULL) {
1748         return err;
1749     }
1750
1751     min_spare_threads = atoi(arg);
1752     if (min_spare_threads <= 0) {
1753        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1754                     "WARNING: detected MinSpareThreads set to non-positive.");
1755        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1756                     "Resetting to 1 to avoid almost certain Apache failure.");
1757        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1758                     "Please read the documentation.");
1759        min_spare_threads = 1;
1760     }
1761        
1762     return NULL;
1763 }
1764
1765 static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy,
1766                                          const char *arg)
1767 {
1768     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1769     if (err != NULL) {
1770         return err;
1771     }
1772
1773     max_spare_threads = atoi(arg);
1774     return NULL;
1775 }
1776
1777 static const char *set_max_clients (cmd_parms *cmd, void *dummy,
1778                                      const char *arg) 
1779 {
1780     int max_clients;
1781     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1782     if (err != NULL) {
1783         return err;
1784     }
1785
1786     /* It is ok to use ap_threads_per_child here because we are
1787      * sure that it gets set before MaxClients in the pre_config stage. */
1788     max_clients = atoi(arg);
1789     if (max_clients < ap_threads_per_child) {
1790        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1791                     "WARNING: MaxClients (%d) must be at least as large",
1792                     max_clients);
1793        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1794                     " large as ThreadsPerChild (%d). Automatically",
1795                     ap_threads_per_child);
1796        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1797                     " increasing MaxClients to %d.",
1798                     ap_threads_per_child);
1799        max_clients = ap_threads_per_child;
1800     }
1801     ap_daemons_limit = max_clients / ap_threads_per_child;
1802     if ((max_clients > 0) && (max_clients % ap_threads_per_child)) {
1803        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1804                     "WARNING: MaxClients (%d) is not an integer multiple",
1805                     max_clients);
1806        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1807                     " of ThreadsPerChild (%d), lowering MaxClients to %d",
1808                     ap_threads_per_child,
1809                     ap_daemons_limit * ap_threads_per_child);
1810        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1811                     " for a maximum of %d child processes,",
1812                     ap_daemons_limit);
1813        max_clients = ap_daemons_limit * ap_threads_per_child; 
1814     }
1815     if (ap_daemons_limit > server_limit) {
1816        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1817                     "WARNING: MaxClients of %d would require %d servers,",
1818                     max_clients, ap_daemons_limit);
1819        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1820                     " and would exceed the ServerLimit value of %d.",
1821                     server_limit);
1822        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1823                     " Automatically lowering MaxClients to %d.  To increase,",
1824                     server_limit * ap_threads_per_child);
1825        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1826                     " please see the ServerLimit directive.");
1827        ap_daemons_limit = server_limit;
1828     } 
1829     else if (ap_daemons_limit < 1) {
1830         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1831                      "WARNING: Require MaxClients > 0, setting to 1");
1832         ap_daemons_limit = 1;
1833     }
1834     return NULL;
1835 }
1836
1837 static const char *set_threads_per_child (cmd_parms *cmd, void *dummy,
1838                                           const char *arg) 
1839 {
1840     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1841     if (err != NULL) {
1842         return err;
1843     }
1844
1845     ap_threads_per_child = atoi(arg);
1846     if (ap_threads_per_child > thread_limit) {
1847         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1848                      "WARNING: ThreadsPerChild of %d exceeds ThreadLimit "
1849                      "value of %d", ap_threads_per_child,
1850                      thread_limit);
1851         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1852                      "threads, lowering ThreadsPerChild to %d. To increase, please"
1853                      " see the", thread_limit);
1854         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1855                      " ThreadLimit directive.");
1856         ap_threads_per_child = thread_limit;
1857     }
1858     else if (ap_threads_per_child < 1) {
1859         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1860                      "WARNING: Require ThreadsPerChild > 0, setting to 1");
1861         ap_threads_per_child = 1;
1862     }
1863     return NULL;
1864 }
1865
1866 static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) 
1867 {
1868     int tmp_server_limit;
1869     
1870     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1871     if (err != NULL) {
1872         return err;
1873     }
1874
1875     tmp_server_limit = atoi(arg);
1876     /* you cannot change ServerLimit across a restart; ignore
1877      * any such attempts
1878      */
1879     if (first_server_limit &&
1880         tmp_server_limit != server_limit) {
1881         /* how do we log a message?  the error log is a bit bucket at this
1882          * point; we'll just have to set a flag so that ap_mpm_run()
1883          * logs a warning later
1884          */
1885         changed_limit_at_restart = 1;
1886         return NULL;
1887     }
1888     server_limit = tmp_server_limit;
1889     
1890     if (server_limit > MAX_SERVER_LIMIT) {
1891        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1892                     "WARNING: ServerLimit of %d exceeds compile time limit "
1893                     "of %d servers,", server_limit, MAX_SERVER_LIMIT);
1894        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1895                     " lowering ServerLimit to %d.", MAX_SERVER_LIMIT);
1896        server_limit = MAX_SERVER_LIMIT;
1897     } 
1898     else if (server_limit < 1) {
1899         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1900                      "WARNING: Require ServerLimit > 0, setting to 1");
1901         server_limit = 1;
1902     }
1903     return NULL;
1904 }
1905
1906 static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) 
1907 {
1908     int tmp_thread_limit;
1909     
1910     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1911     if (err != NULL) {
1912         return err;
1913     }
1914
1915     tmp_thread_limit = atoi(arg);
1916     /* you cannot change ThreadLimit across a restart; ignore
1917      * any such attempts
1918      */
1919     if (first_thread_limit &&
1920         tmp_thread_limit != thread_limit) {
1921         /* how do we log a message?  the error log is a bit bucket at this
1922          * point; we'll just have to set a flag so that ap_mpm_run()
1923          * logs a warning later
1924          */
1925         changed_limit_at_restart = 1;
1926         return NULL;
1927     }
1928     thread_limit = tmp_thread_limit;
1929     
1930     if (thread_limit > MAX_THREAD_LIMIT) {
1931        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1932                     "WARNING: ThreadLimit of %d exceeds compile time limit "
1933                     "of %d servers,", thread_limit, MAX_THREAD_LIMIT);
1934        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1935                     " lowering ThreadLimit to %d.", MAX_THREAD_LIMIT);
1936        thread_limit = MAX_THREAD_LIMIT;
1937     } 
1938     else if (thread_limit < 1) {
1939         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1940                      "WARNING: Require ThreadLimit > 0, setting to 1");
1941         thread_limit = 1;
1942     }
1943     return NULL;
1944 }
1945
1946 static const command_rec leader_cmds[] = {
1947 UNIX_DAEMON_COMMANDS,
1948 LISTEN_COMMANDS,
1949 AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
1950   "Number of child processes launched at server startup"),
1951 AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF,
1952   "Minimum number of idle children, to handle request spikes"),
1953 AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF,
1954   "Maximum number of idle children"),
1955 AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF,
1956   "Maximum number of children alive at the same time"),
1957 AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF,
1958   "Number of threads each child creates"),
1959 AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF,
1960   "Maximum value of MaxClients for this run of Apache"),
1961 AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF,
1962   "Maximum worker threads in a server for this run of Apache"),
1963 { NULL }
1964 };
1965
1966 module AP_MODULE_DECLARE_DATA mpm_leader_module = {
1967     MPM20_MODULE_STUFF,
1968     ap_mpm_rewrite_args,        /* hook to run before apache parses args */
1969     NULL,                       /* create per-directory config structure */
1970     NULL,                       /* merge per-directory config structures */
1971     NULL,                       /* create per-server config structure */
1972     NULL,                       /* merge per-server config structures */
1973     leader_cmds,                /* command apr_table_t */
1974     leader_hooks                /* register_hooks */
1975 };
1976