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