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