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