]> granicus.if.org Git - apache/blob - server/mpm/worker/worker.c
0a05b07646fbaa919e31929a0788107df02ecfb2
[apache] / server / mpm / worker / worker.c
1 /* ====================================================================
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2000-2003 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     if (csd >= FD_SETSIZE) {
561         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL,
562                      "new file descriptor %d is too large; you probably need "
563                      "to rebuild Apache with a larger FD_SETSIZE "
564                      "(currently %d)", 
565                      csd, FD_SETSIZE);
566         apr_socket_close(sock);
567         return;
568     }
569
570     current_conn = ap_run_create_connection(p, ap_server_conf, sock,
571                                             conn_id, sbh, bucket_alloc);
572     if (current_conn) {
573         ap_process_connection(current_conn, sock);
574         ap_lingering_close(current_conn);
575     }
576 }
577
578 /* requests_this_child has gone to zero or below.  See if the admin coded
579    "MaxRequestsPerChild 0", and keep going in that case.  Doing it this way
580    simplifies the hot path in worker_thread */
581 static void check_infinite_requests(void)
582 {
583     if (ap_max_requests_per_child) {
584         signal_threads(ST_GRACEFUL);
585     }
586     else {
587         /* wow! if you're executing this code, you may have set a record.
588          * either this child process has served over 2 billion requests, or
589          * you're running a threaded 2.0 on a 16 bit machine.  
590          *
591          * I'll buy pizza and beers at Apachecon for the first person to do
592          * the former without cheating (dorking with INT_MAX, or running with
593          * uncommitted performance patches, for example).    
594          *
595          * for the latter case, you probably deserve a beer too.   Greg Ames
596          */
597             
598         requests_this_child = INT_MAX;      /* keep going */ 
599     }
600 }
601
602 static void unblock_signal(int sig)
603 {
604     sigset_t sig_mask;
605
606     sigemptyset(&sig_mask);
607     sigaddset(&sig_mask, sig);
608 #if defined(SIGPROCMASK_SETS_THREAD_MASK)
609     sigprocmask(SIG_UNBLOCK, &sig_mask, NULL);
610 #else
611     pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL);
612 #endif
613 }
614
615 static void dummy_signal_handler(int sig)
616 {
617     /* XXX If specifying SIG_IGN is guaranteed to unblock a syscall,
618      *     then we don't need this goofy function.
619      */
620 }
621
622 static void *listener_thread(apr_thread_t *thd, void * dummy)
623 {
624     proc_info * ti = dummy;
625     int process_slot = ti->pid;
626     apr_pool_t *tpool = apr_thread_pool_get(thd);
627     void *csd = NULL;
628     apr_pool_t *ptrans;                /* Pool for per-transaction stuff */
629     apr_pool_t *recycled_pool = NULL;
630     apr_pollset_t *pollset;
631     apr_status_t rv;
632     ap_listen_rec *lr;
633     int have_idle_worker = 0;
634     int last_poll_idx = 0;
635
636     free(ti);
637
638     /* ### check the status */
639     (void) apr_pollset_create(&pollset, num_listensocks, tpool, 0);
640
641     for (lr = ap_listeners; lr != NULL; lr = lr->next) {
642         apr_pollfd_t pfd = { 0 };
643
644         pfd.desc_type = APR_POLL_SOCKET;
645         pfd.desc.s = lr->sd;
646         pfd.reqevents = APR_POLLIN;
647         pfd.client_data = lr;
648
649         /* ### check the status */
650         (void) apr_pollset_add(pollset, &pfd);
651     }
652
653     /* Unblock the signal used to wake this thread up, and set a handler for
654      * it.
655      */
656     unblock_signal(LISTENER_SIGNAL);
657     apr_signal(LISTENER_SIGNAL, dummy_signal_handler);
658
659     /* TODO: Switch to a system where threads reuse the results from earlier
660        poll calls - manoj */
661     while (1) {
662         /* TODO: requests_this_child should be synchronized - aaron */
663         if (requests_this_child <= 0) {
664             check_infinite_requests();
665         }
666         if (listener_may_exit) break;
667
668         if (!have_idle_worker) {
669             rv = ap_queue_info_wait_for_idler(worker_queue_info,
670                                               &recycled_pool);
671             if (APR_STATUS_IS_EOF(rv)) {
672                 break; /* we've been signaled to die now */
673             }
674             else if (rv != APR_SUCCESS) {
675                 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
676                              "apr_queue_info_wait failed. Attempting to "
677                              " shutdown process gracefully.");
678                 signal_threads(ST_GRACEFUL);
679                 break;
680             }
681             have_idle_worker = 1;
682         }
683             
684         /* We've already decremented the idle worker count inside
685          * ap_queue_info_wait_for_idler. */
686
687         if ((rv = SAFE_ACCEPT(apr_proc_mutex_lock(accept_mutex)))
688             != APR_SUCCESS) {
689             int level = APLOG_EMERG;
690
691             if (listener_may_exit) {
692                 break;
693             }
694             if (ap_scoreboard_image->parent[process_slot].generation != 
695                 ap_scoreboard_image->global->running_generation) {
696                 level = APLOG_DEBUG; /* common to get these at restart time */
697             }
698             ap_log_error(APLOG_MARK, level, rv, ap_server_conf,
699                          "apr_proc_mutex_lock failed. Attempting to shutdown "
700                          "process gracefully.");
701             signal_threads(ST_GRACEFUL);
702             break;                    /* skip the lock release */
703         }
704
705         if (!ap_listeners->next) {
706             /* Only one listener, so skip the poll */
707             lr = ap_listeners;
708         }
709         else {
710             while (!listener_may_exit) {
711                 apr_int32_t numdesc;
712                 const apr_pollfd_t *pdesc;
713
714                 rv = apr_pollset_poll(pollset, -1, &numdesc, &pdesc);
715                 if (rv != APR_SUCCESS) {
716                     if (APR_STATUS_IS_EINTR(rv)) {
717                         continue;
718                     }
719
720                     /* apr_pollset_poll() will only return errors in catastrophic
721                      * circumstances. Let's try exiting gracefully, for now. */
722                     ap_log_error(APLOG_MARK, APLOG_ERR, rv,
723                                  (const server_rec *) ap_server_conf,
724                                  "apr_pollset_poll: (listen)");
725                     signal_threads(ST_GRACEFUL);
726                 }
727
728                 if (listener_may_exit) break;
729
730                 /* We can always use pdesc[0], but sockets at position N
731                  * could end up completely starved of attention in a very
732                  * busy server. Therefore, we round-robin across the
733                  * returned set of descriptors. While it is possible that
734                  * the returned set of descriptors might flip around and
735                  * continue to starve some sockets, we happen to know the
736                  * internal pollset implementation retains ordering
737                  * stability of the sockets. Thus, the round-robin should
738                  * ensure that a socket will eventually be serviced.
739                  */
740                 if (last_poll_idx >= numdesc)
741                     last_poll_idx = 0;
742
743                 /* Grab a listener record from the client_data of the poll
744                  * descriptor, and advance our saved index to round-robin
745                  * the next fetch.
746                  *
747                  * ### hmm... this descriptor might have POLLERR rather
748                  * ### than POLLIN
749                  */
750                 lr = pdesc[last_poll_idx++].client_data;
751                 break;
752
753             } /* while */
754
755         } /* if/else */
756
757         if (!listener_may_exit) {
758             /* create a new transaction pool for each accepted socket */
759             if (recycled_pool == NULL) {
760                 apr_allocator_t *allocator;
761
762                 apr_allocator_create(&allocator);
763                 apr_allocator_max_free_set(allocator, ap_max_mem_free);
764                 apr_pool_create_ex(&ptrans, NULL, NULL, allocator);
765                 apr_allocator_owner_set(allocator, ptrans);
766             }
767             else {
768                 ptrans = recycled_pool;
769             }
770             apr_pool_tag(ptrans, "transaction");
771             rv = lr->accept_func(&csd, lr, ptrans);
772             /* later we trash rv and rely on csd to indicate success/failure */
773             AP_DEBUG_ASSERT(rv == APR_SUCCESS || !csd);
774
775             if (rv == APR_EGENERAL) {
776                 /* E[NM]FILE, ENOMEM, etc */
777                 resource_shortage = 1;
778                 signal_threads(ST_GRACEFUL);
779             }
780             if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex)))
781                 != APR_SUCCESS) {
782                 int level = APLOG_EMERG;
783
784                 if (listener_may_exit) {
785                     break;
786                 }
787                 if (ap_scoreboard_image->parent[process_slot].generation != 
788                     ap_scoreboard_image->global->running_generation) {
789                     level = APLOG_DEBUG; /* common to get these at restart time */
790                 }
791                 ap_log_error(APLOG_MARK, level, rv, ap_server_conf,
792                              "apr_proc_mutex_unlock failed. Attempting to "
793                              "shutdown process gracefully.");
794                 signal_threads(ST_GRACEFUL);
795             }
796             if (csd != NULL) {
797                 rv = ap_queue_push(worker_queue, csd, ptrans);
798                 if (rv) {
799                     /* trash the connection; we couldn't queue the connected
800                      * socket to a worker 
801                      */
802                     apr_socket_close(csd);
803                     ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
804                                  "ap_queue_push failed");
805                 }
806                 else {
807                     have_idle_worker = 0;
808                 }
809             }
810         }
811         else {
812             if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex)))
813                 != APR_SUCCESS) {
814                 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
815                              "apr_proc_mutex_unlock failed. Attempting to "
816                              "shutdown process gracefully.");
817                 signal_threads(ST_GRACEFUL);
818             }
819             break;
820         }
821     }
822
823     ap_queue_term(worker_queue);
824     dying = 1;
825     ap_scoreboard_image->parent[process_slot].quiescing = 1;
826
827     /* wake up the main thread */
828     kill(ap_my_pid, SIGTERM);
829
830     apr_thread_exit(thd, APR_SUCCESS);
831     return NULL;
832 }
833
834 /* XXX For ungraceful termination/restart, we definitely don't want to
835  *     wait for active connections to finish but we may want to wait
836  *     for idle workers to get out of the queue code and release mutexes,
837  *     since those mutexes are cleaned up pretty soon and some systems
838  *     may not react favorably (i.e., segfault) if operations are attempted
839  *     on cleaned-up mutexes.
840  */
841 static void * APR_THREAD_FUNC worker_thread(apr_thread_t *thd, void * dummy)
842 {
843     proc_info * ti = dummy;
844     int process_slot = ti->pid;
845     int thread_slot = ti->tid;
846     apr_socket_t *csd = NULL;
847     apr_bucket_alloc_t *bucket_alloc;
848     apr_pool_t *last_ptrans = NULL;
849     apr_pool_t *ptrans;                /* Pool for per-transaction stuff */
850     apr_status_t rv;
851     int is_idle = 0;
852
853     free(ti);
854
855     ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL);
856
857     while (!workers_may_exit) {
858         if (!is_idle) {
859             rv = ap_queue_info_set_idle(worker_queue_info, last_ptrans);
860             last_ptrans = NULL;
861             if (rv != APR_SUCCESS) {
862                 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
863                              "ap_queue_info_set_idle failed. Attempting to "
864                              "shutdown process gracefully.");
865                 signal_threads(ST_GRACEFUL);
866                 break;
867             }
868             is_idle = 1;
869         }
870
871         ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_READY, NULL);
872 worker_pop:
873         if (workers_may_exit) {
874             break;
875         }
876         rv = ap_queue_pop(worker_queue, &csd, &ptrans);
877
878         if (rv != APR_SUCCESS) {
879             /* We get APR_EOF during a graceful shutdown once all the connections
880              * accepted by this server process have been handled.
881              */
882             if (APR_STATUS_IS_EOF(rv)) {
883                 break;
884             }
885             /* We get APR_EINTR whenever ap_queue_pop() has been interrupted
886              * from an explicit call to ap_queue_interrupt_all(). This allows
887              * us to unblock threads stuck in ap_queue_pop() when a shutdown
888              * is pending.
889              *
890              * If workers_may_exit is set and this is ungraceful termination/
891              * restart, we are bound to get an error on some systems (e.g.,
892              * AIX, which sanity-checks mutex operations) since the queue
893              * may have already been cleaned up.  Don't log the "error" if
894              * workers_may_exit is set.
895              */
896             else if (APR_STATUS_IS_EINTR(rv)) {
897                 goto worker_pop;
898             }
899             /* We got some other error. */
900             else if (!workers_may_exit) {
901                 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
902                              "ap_queue_pop failed");
903             }
904             continue;
905         }
906         is_idle = 0;
907         worker_sockets[thread_slot] = csd;
908         bucket_alloc = apr_bucket_alloc_create(ptrans);
909         process_socket(ptrans, csd, process_slot, thread_slot, bucket_alloc);
910         worker_sockets[thread_slot] = NULL;
911         requests_this_child--; /* FIXME: should be synchronized - aaron */
912         apr_pool_clear(ptrans);
913         last_ptrans = ptrans;
914     }
915
916     ap_update_child_status_from_indexes(process_slot, thread_slot,
917         (dying) ? SERVER_DEAD : SERVER_GRACEFUL, (request_rec *) NULL);
918
919     apr_thread_exit(thd, APR_SUCCESS);
920     return NULL;
921 }
922
923 static int check_signal(int signum)
924 {
925     switch (signum) {
926     case SIGTERM:
927     case SIGINT:
928         return 1;
929     }
930     return 0;
931 }
932
933 static void create_listener_thread(thread_starter *ts)
934 {
935     int my_child_num = ts->child_num_arg;
936     apr_threadattr_t *thread_attr = ts->threadattr;
937     proc_info *my_info;
938     apr_status_t rv;
939
940     my_info = (proc_info *)malloc(sizeof(proc_info));
941     my_info->pid = my_child_num;
942     my_info->tid = -1; /* listener thread doesn't have a thread slot */
943     my_info->sd = 0;
944     rv = apr_thread_create(&ts->listener, thread_attr, listener_thread,
945                            my_info, pchild);
946     if (rv != APR_SUCCESS) {
947         ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
948                      "apr_thread_create: unable to create listener thread");
949         /* In case system resources are maxxed out, we don't want
950          * Apache running away with the CPU trying to fork over and
951          * over and over again if we exit.
952          * XXX Jeff doesn't see how Apache is going to try to fork again since
953          * the exit code is APEXIT_CHILDFATAL
954          */
955         apr_sleep(apr_time_from_sec(10));
956         clean_child_exit(APEXIT_CHILDFATAL);
957     }
958     apr_os_thread_get(&listener_os_thread, ts->listener);
959 }
960
961 /* XXX under some circumstances not understood, children can get stuck
962  *     in start_threads forever trying to take over slots which will
963  *     never be cleaned up; for now there is an APLOG_DEBUG message issued
964  *     every so often when this condition occurs
965  */
966 static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy)
967 {
968     thread_starter *ts = dummy;
969     apr_thread_t **threads = ts->threads;
970     apr_threadattr_t *thread_attr = ts->threadattr;
971     int child_num_arg = ts->child_num_arg;
972     int my_child_num = child_num_arg;
973     proc_info *my_info;
974     apr_status_t rv;
975     int i;
976     int threads_created = 0;
977     int listener_started = 0;
978     int loops;
979     int prev_threads_created;
980
981     /* We must create the fd queues before we start up the listener
982      * and worker threads. */
983     worker_queue = apr_pcalloc(pchild, sizeof(*worker_queue));
984     rv = ap_queue_init(worker_queue, ap_threads_per_child, pchild);
985     if (rv != APR_SUCCESS) {
986         ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
987                      "ap_queue_init() failed");
988         clean_child_exit(APEXIT_CHILDFATAL);
989     }
990
991     rv = ap_queue_info_create(&worker_queue_info, pchild,
992                               ap_threads_per_child);
993     if (rv != APR_SUCCESS) {
994         ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
995                      "ap_queue_info_create() failed");
996         clean_child_exit(APEXIT_CHILDFATAL);
997     }
998
999     worker_sockets = apr_pcalloc(pchild, ap_threads_per_child
1000                                         * sizeof(apr_socket_t *));
1001
1002     loops = prev_threads_created = 0;
1003     while (1) {
1004         /* ap_threads_per_child does not include the listener thread */
1005         for (i = 0; i < ap_threads_per_child; i++) {
1006             int status = ap_scoreboard_image->servers[child_num_arg][i].status;
1007
1008             if (status != SERVER_GRACEFUL && status != SERVER_DEAD) {
1009                 continue;
1010             }
1011
1012             my_info = (proc_info *)malloc(sizeof(proc_info));
1013             if (my_info == NULL) {
1014                 ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf,
1015                              "malloc: out of memory");
1016                 clean_child_exit(APEXIT_CHILDFATAL);
1017             }
1018             my_info->pid = my_child_num;
1019             my_info->tid = i;
1020             my_info->sd = 0;
1021         
1022             /* We are creating threads right now */
1023             ap_update_child_status_from_indexes(my_child_num, i,
1024                                                 SERVER_STARTING, NULL);
1025             /* We let each thread update its own scoreboard entry.  This is
1026              * done because it lets us deal with tid better.
1027              */
1028             rv = apr_thread_create(&threads[i], thread_attr, 
1029                                    worker_thread, my_info, pchild);
1030             if (rv != APR_SUCCESS) {
1031                 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1032                     "apr_thread_create: unable to create worker thread");
1033                 /* In case system resources are maxxed out, we don't want
1034                    Apache running away with the CPU trying to fork over and
1035                    over and over again if we exit. */
1036                 apr_sleep(apr_time_from_sec(10));
1037                 clean_child_exit(APEXIT_CHILDFATAL);
1038             }
1039             threads_created++;
1040         }
1041         /* Start the listener only when there are workers available */
1042         if (!listener_started && threads_created) {
1043             create_listener_thread(ts);
1044             listener_started = 1;
1045         }
1046         if (start_thread_may_exit || threads_created == ap_threads_per_child) {
1047             break;
1048         }
1049         /* wait for previous generation to clean up an entry */
1050         apr_sleep(apr_time_from_sec(1));
1051         ++loops;
1052         if (loops % 120 == 0) { /* every couple of minutes */
1053             if (prev_threads_created == threads_created) {
1054                 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1055                              "child %" APR_PID_T_FMT " isn't taking over "
1056                              "slots very quickly (%d of %d)",
1057                              ap_my_pid, threads_created, ap_threads_per_child);
1058             }
1059             prev_threads_created = threads_created;
1060         }
1061     }
1062     
1063     /* What state should this child_main process be listed as in the 
1064      * scoreboard...?
1065      *  ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING, 
1066      *                                      (request_rec *) NULL);
1067      * 
1068      *  This state should be listed separately in the scoreboard, in some kind
1069      *  of process_status, not mixed in with the worker threads' status.   
1070      *  "life_status" is almost right, but it's in the worker's structure, and 
1071      *  the name could be clearer.   gla
1072      */
1073     apr_thread_exit(thd, APR_SUCCESS);
1074     return NULL;
1075 }
1076
1077 static void join_workers(apr_thread_t *listener, apr_thread_t **threads)
1078 {
1079     int i;
1080     apr_status_t rv, thread_rv;
1081
1082     if (listener) {
1083         int iter;
1084         
1085         /* deal with a rare timing window which affects waking up the
1086          * listener thread...  if the signal sent to the listener thread
1087          * is delivered between the time it verifies that the
1088          * listener_may_exit flag is clear and the time it enters a
1089          * blocking syscall, the signal didn't do any good...  work around
1090          * that by sleeping briefly and sending it again
1091          */
1092
1093         iter = 0;
1094         while (iter < 10 && 
1095 #ifdef HAVE_PTHREAD_KILL
1096                pthread_kill(*listener_os_thread, 0)
1097 #else
1098                kill(ap_my_pid, 0)
1099 #endif
1100                == 0) {
1101             /* listener not dead yet */
1102             apr_sleep(apr_time_make(0, 500000));
1103             wakeup_listener();
1104             ++iter;
1105         }
1106         if (iter >= 10) {
1107             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1108                          "the listener thread didn't exit");
1109         }
1110         else {
1111             rv = apr_thread_join(&thread_rv, listener);
1112             if (rv != APR_SUCCESS) {
1113                 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1114                              "apr_thread_join: unable to join listener thread");
1115             }
1116         }
1117     }
1118     
1119     for (i = 0; i < ap_threads_per_child; i++) {
1120         if (threads[i]) { /* if we ever created this thread */
1121             rv = apr_thread_join(&thread_rv, threads[i]);
1122             if (rv != APR_SUCCESS) {
1123                 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1124                              "apr_thread_join: unable to join worker "
1125                              "thread %d",
1126                              i);
1127             }
1128         }
1129     }
1130 }
1131
1132 static void join_start_thread(apr_thread_t *start_thread_id)
1133 {
1134     apr_status_t rv, thread_rv;
1135
1136     start_thread_may_exit = 1; /* tell it to give up in case it is still 
1137                                 * trying to take over slots from a 
1138                                 * previous generation
1139                                 */
1140     rv = apr_thread_join(&thread_rv, start_thread_id);
1141     if (rv != APR_SUCCESS) {
1142         ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1143                      "apr_thread_join: unable to join the start "
1144                      "thread");
1145     }
1146 }
1147
1148 static void child_main(int child_num_arg)
1149 {
1150     apr_thread_t **threads;
1151     apr_status_t rv;
1152     thread_starter *ts;
1153     apr_threadattr_t *thread_attr;
1154     apr_thread_t *start_thread_id;
1155
1156     mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
1157                                    * child initializes
1158                                    */
1159     ap_my_pid = getpid();
1160     ap_fatal_signal_child_setup(ap_server_conf);
1161     apr_pool_create(&pchild, pconf);
1162
1163     /*stuff to do before we switch id's, so we have permissions.*/
1164     ap_reopen_scoreboard(pchild, NULL, 0);
1165
1166     rv = SAFE_ACCEPT(apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname,
1167                                                pchild));
1168     if (rv != APR_SUCCESS) {
1169         ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
1170                      "Couldn't initialize cross-process lock in child");
1171         clean_child_exit(APEXIT_CHILDFATAL);
1172     }
1173
1174     if (unixd_setup_child()) {
1175         clean_child_exit(APEXIT_CHILDFATAL);
1176     }
1177
1178     ap_run_child_init(pchild, ap_server_conf);
1179
1180     /* done with init critical section */
1181
1182     /* Just use the standard apr_setup_signal_thread to block all signals
1183      * from being received.  The child processes no longer use signals for
1184      * any communication with the parent process.
1185      */
1186     rv = apr_setup_signal_thread();
1187     if (rv != APR_SUCCESS) {
1188         ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
1189                      "Couldn't initialize signal thread");
1190         clean_child_exit(APEXIT_CHILDFATAL);
1191     }
1192
1193     if (ap_max_requests_per_child) {
1194         requests_this_child = ap_max_requests_per_child;
1195     }
1196     else {
1197         /* coding a value of zero means infinity */
1198         requests_this_child = INT_MAX;
1199     }
1200     
1201     /* Setup worker threads */
1202
1203     /* clear the storage; we may not create all our threads immediately, 
1204      * and we want a 0 entry to indicate a thread which was not created
1205      */
1206     threads = (apr_thread_t **)calloc(1, 
1207                                 sizeof(apr_thread_t *) * ap_threads_per_child);
1208     if (threads == NULL) {
1209         ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf,
1210                      "malloc: out of memory");
1211         clean_child_exit(APEXIT_CHILDFATAL);
1212     }
1213
1214     ts = (thread_starter *)apr_palloc(pchild, sizeof(*ts));
1215
1216     apr_threadattr_create(&thread_attr, pchild);
1217     /* 0 means PTHREAD_CREATE_JOINABLE */
1218     apr_threadattr_detach_set(thread_attr, 0);
1219
1220     ts->threads = threads;
1221     ts->listener = NULL;
1222     ts->child_num_arg = child_num_arg;
1223     ts->threadattr = thread_attr;
1224
1225     rv = apr_thread_create(&start_thread_id, thread_attr, start_threads,
1226                            ts, pchild);
1227     if (rv != APR_SUCCESS) {
1228         ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1229                      "apr_thread_create: unable to create worker thread");
1230         /* In case system resources are maxxed out, we don't want
1231            Apache running away with the CPU trying to fork over and
1232            over and over again if we exit. */
1233         apr_sleep(apr_time_from_sec(10));
1234         clean_child_exit(APEXIT_CHILDFATAL);
1235     }
1236
1237     mpm_state = AP_MPMQ_RUNNING;
1238
1239     /* If we are only running in one_process mode, we will want to
1240      * still handle signals. */
1241     if (one_process) {
1242         /* Block until we get a terminating signal. */
1243         apr_signal_thread(check_signal);
1244         /* make sure the start thread has finished; signal_threads() 
1245          * and join_workers() depend on that
1246          */
1247         /* XXX join_start_thread() won't be awakened if one of our
1248          *     threads encounters a critical error and attempts to
1249          *     shutdown this child
1250          */
1251         join_start_thread(start_thread_id);
1252         signal_threads(ST_UNGRACEFUL); /* helps us terminate a little more
1253                            * quickly than the dispatch of the signal thread
1254                            * beats the Pipe of Death and the browsers
1255                            */
1256         /* A terminating signal was received. Now join each of the
1257          * workers to clean them up.
1258          *   If the worker already exited, then the join frees
1259          *   their resources and returns.
1260          *   If the worker hasn't exited, then this blocks until
1261          *   they have (then cleans up).
1262          */
1263         join_workers(ts->listener, threads);
1264     }
1265     else { /* !one_process */
1266         /* remove SIGTERM from the set of blocked signals...  if one of
1267          * the other threads in the process needs to take us down
1268          * (e.g., for MaxRequestsPerChild) it will send us SIGTERM
1269          */
1270         unblock_signal(SIGTERM);
1271         apr_signal(SIGTERM, dummy_signal_handler);
1272         /* Watch for any messages from the parent over the POD */
1273         while (1) {
1274             rv = ap_mpm_pod_check(pod);
1275             if (rv == AP_NORESTART) {
1276                 /* see if termination was triggered while we slept */
1277                 switch(terminate_mode) {
1278                 case ST_GRACEFUL:
1279                     rv = AP_GRACEFUL;
1280                     break;
1281                 case ST_UNGRACEFUL:
1282                     rv = AP_RESTART;
1283                     break;
1284                 }
1285             }
1286             if (rv == AP_GRACEFUL || rv == AP_RESTART) {
1287                 /* make sure the start thread has finished; 
1288                  * signal_threads() and join_workers depend on that
1289                  */
1290                 join_start_thread(start_thread_id);
1291                 signal_threads(rv == AP_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL);
1292                 break;
1293             }
1294         }
1295
1296         /* A terminating signal was received. Now join each of the
1297          * workers to clean them up.
1298          *   If the worker already exited, then the join frees
1299          *   their resources and returns.
1300          *   If the worker hasn't exited, then this blocks until
1301          *   they have (then cleans up).
1302          */
1303         join_workers(ts->listener, threads);
1304     }
1305
1306     free(threads);
1307
1308     clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0);
1309 }
1310
1311 static int make_child(server_rec *s, int slot) 
1312 {
1313     int pid;
1314
1315     if (slot + 1 > ap_max_daemons_limit) {
1316         ap_max_daemons_limit = slot + 1;
1317     }
1318
1319     if (one_process) {
1320         set_signals();
1321         ap_scoreboard_image->parent[slot].pid = getpid();
1322         child_main(slot);
1323     }
1324
1325     if ((pid = fork()) == -1) {
1326         ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, 
1327                      "fork: Unable to fork new process");
1328
1329         /* fork didn't succeed. Fix the scoreboard or else
1330          * it will say SERVER_STARTING forever and ever
1331          */
1332         ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, NULL);
1333
1334         /* In case system resources are maxxed out, we don't want
1335            Apache running away with the CPU trying to fork over and
1336            over and over again. */
1337         apr_sleep(apr_time_from_sec(10));
1338
1339         return -1;
1340     }
1341
1342     if (!pid) {
1343 #ifdef HAVE_BINDPROCESSOR
1344         /* By default, AIX binds to a single processor.  This bit unbinds
1345          * children which will then bind to another CPU.
1346          */
1347         int status = bindprocessor(BINDPROCESS, (int)getpid(),
1348                                PROCESSOR_CLASS_ANY);
1349         if (status != OK)
1350             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, 
1351                          ap_server_conf,
1352                          "processor unbind failed %d", status);
1353 #endif
1354         RAISE_SIGSTOP(MAKE_CHILD);
1355
1356         apr_signal(SIGTERM, just_die);
1357         child_main(slot);
1358
1359         clean_child_exit(0);
1360     }
1361     /* else */
1362     ap_scoreboard_image->parent[slot].quiescing = 0;
1363     ap_scoreboard_image->parent[slot].pid = pid;
1364     return 0;
1365 }
1366
1367 /* start up a bunch of children */
1368 static void startup_children(int number_to_start)
1369 {
1370     int i;
1371
1372     for (i = 0; number_to_start && i < ap_daemons_limit; ++i) {
1373         if (ap_scoreboard_image->parent[i].pid != 0) {
1374             continue;
1375         }
1376         if (make_child(ap_server_conf, i) < 0) {
1377             break;
1378         }
1379         --number_to_start;
1380     }
1381 }
1382
1383
1384 /*
1385  * idle_spawn_rate is the number of children that will be spawned on the
1386  * next maintenance cycle if there aren't enough idle servers.  It is
1387  * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
1388  * without the need to spawn.
1389  */
1390 static int idle_spawn_rate = 1;
1391 #ifndef MAX_SPAWN_RATE
1392 #define MAX_SPAWN_RATE        (32)
1393 #endif
1394 static int hold_off_on_exponential_spawning;
1395
1396 static void perform_idle_server_maintenance(void)
1397 {
1398     int i, j;
1399     int idle_thread_count;
1400     worker_score *ws;
1401     process_score *ps;
1402     int free_length;
1403     int totally_free_length = 0;
1404     int free_slots[MAX_SPAWN_RATE];
1405     int last_non_dead;
1406     int total_non_dead;
1407
1408     /* initialize the free_list */
1409     free_length = 0;
1410
1411     idle_thread_count = 0;
1412     last_non_dead = -1;
1413     total_non_dead = 0;
1414
1415     for (i = 0; i < ap_daemons_limit; ++i) {
1416         /* Initialization to satisfy the compiler. It doesn't know
1417          * that ap_threads_per_child is always > 0 */
1418         int status = SERVER_DEAD;
1419         int any_dying_threads = 0;
1420         int any_dead_threads = 0;
1421         int all_dead_threads = 1;
1422
1423         if (i >= ap_max_daemons_limit && totally_free_length == idle_spawn_rate)
1424             break;
1425         ps = &ap_scoreboard_image->parent[i];
1426         for (j = 0; j < ap_threads_per_child; j++) {
1427             ws = &ap_scoreboard_image->servers[i][j];
1428             status = ws->status;
1429
1430             /* XXX any_dying_threads is probably no longer needed    GLA */
1431             any_dying_threads = any_dying_threads || 
1432                                 (status == SERVER_GRACEFUL);
1433             any_dead_threads = any_dead_threads || (status == SERVER_DEAD);
1434             all_dead_threads = all_dead_threads &&
1435                                    (status == SERVER_DEAD ||
1436                                     status == SERVER_GRACEFUL);
1437
1438             /* We consider a starting server as idle because we started it
1439              * at least a cycle ago, and if it still hasn't finished starting
1440              * then we're just going to swamp things worse by forking more.
1441              * So we hopefully won't need to fork more if we count it.
1442              * This depends on the ordering of SERVER_READY and SERVER_STARTING.
1443              */
1444             if (status <= SERVER_READY && status != SERVER_DEAD &&
1445                     !ps->quiescing &&
1446                     ps->generation == ap_my_generation &&
1447                  /* XXX the following shouldn't be necessary if we clean up 
1448                   *     properly after seg faults, but we're not yet    GLA 
1449                   */     
1450                     ps->pid != 0) {
1451                 ++idle_thread_count;
1452             }
1453         }
1454         if (any_dead_threads && totally_free_length < idle_spawn_rate 
1455                 && (!ps->pid               /* no process in the slot */
1456                     || ps->quiescing)) {   /* or at least one is going away */
1457             if (all_dead_threads) {
1458                 /* great! we prefer these, because the new process can
1459                  * start more threads sooner.  So prioritize this slot 
1460                  * by putting it ahead of any slots with active threads.
1461                  *
1462                  * first, make room by moving a slot that's potentially still
1463                  * in use to the end of the array
1464                  */
1465                 free_slots[free_length] = free_slots[totally_free_length];
1466                 free_slots[totally_free_length++] = i;
1467             }
1468             else {
1469                 /* slot is still in use - back of the bus
1470                  */
1471             free_slots[free_length] = i;
1472             }
1473             ++free_length;
1474         }
1475         /* XXX if (!ps->quiescing)     is probably more reliable  GLA */
1476         if (!any_dying_threads) {
1477             last_non_dead = i;
1478             ++total_non_dead;
1479         }
1480     }
1481     ap_max_daemons_limit = last_non_dead + 1;
1482
1483     if (idle_thread_count > max_spare_threads) {
1484         /* Kill off one child */
1485         ap_mpm_pod_signal(pod, TRUE);
1486         idle_spawn_rate = 1;
1487     }
1488     else if (idle_thread_count < min_spare_threads) {
1489         /* terminate the free list */
1490         if (free_length == 0) {
1491             /* only report this condition once */
1492             static int reported = 0;
1493             
1494             if (!reported) {
1495                 ap_log_error(APLOG_MARK, APLOG_ERR, 0, 
1496                              ap_server_conf,
1497                              "server reached MaxClients setting, consider"
1498                              " raising the MaxClients setting");
1499                 reported = 1;
1500             }
1501             idle_spawn_rate = 1;
1502         }
1503         else {
1504             if (free_length > idle_spawn_rate) {
1505                 free_length = idle_spawn_rate;
1506             }
1507             if (idle_spawn_rate >= 8) {
1508                 ap_log_error(APLOG_MARK, APLOG_INFO, 0, 
1509                              ap_server_conf,
1510                              "server seems busy, (you may need "
1511                              "to increase StartServers, ThreadsPerChild "
1512                              "or Min/MaxSpareThreads), "
1513                              "spawning %d children, there are around %d idle "
1514                              "threads, and %d total children", free_length,
1515                              idle_thread_count, total_non_dead);
1516             }
1517             for (i = 0; i < free_length; ++i) {
1518                 make_child(ap_server_conf, free_slots[i]);
1519             }
1520             /* the next time around we want to spawn twice as many if this
1521              * wasn't good enough, but not if we've just done a graceful
1522              */
1523             if (hold_off_on_exponential_spawning) {
1524                 --hold_off_on_exponential_spawning;
1525             }
1526             else if (idle_spawn_rate < MAX_SPAWN_RATE) {
1527                 idle_spawn_rate *= 2;
1528             }
1529         }
1530     }
1531     else {
1532       idle_spawn_rate = 1;
1533     }
1534 }
1535
1536 static void server_main_loop(int remaining_children_to_start)
1537 {
1538     int child_slot;
1539     apr_exit_why_e exitwhy;
1540     int status, processed_status;
1541     apr_proc_t pid;
1542     int i;
1543
1544     while (!restart_pending && !shutdown_pending) {
1545         ap_wait_or_timeout(&exitwhy, &status, &pid, pconf);
1546         
1547         if (pid.pid != -1) {
1548             processed_status = ap_process_child_status(&pid, exitwhy, status);
1549             if (processed_status == APEXIT_CHILDFATAL) {
1550                 shutdown_pending = 1;
1551                 child_fatal = 1;
1552                 return;
1553             }
1554             /* non-fatal death... note that it's gone in the scoreboard. */
1555             child_slot = find_child_by_pid(&pid);
1556             if (child_slot >= 0) {
1557                 for (i = 0; i < ap_threads_per_child; i++)
1558                     ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD, 
1559                                                         (request_rec *) NULL);
1560                 
1561                 ap_scoreboard_image->parent[child_slot].pid = 0;
1562                 ap_scoreboard_image->parent[child_slot].quiescing = 0;
1563                 if (processed_status == APEXIT_CHILDSICK) {
1564                     /* resource shortage, minimize the fork rate */
1565                     idle_spawn_rate = 1;
1566                 }
1567                 else if (remaining_children_to_start
1568                     && child_slot < ap_daemons_limit) {
1569                     /* we're still doing a 1-for-1 replacement of dead
1570                      * children with new children
1571                      */
1572                     make_child(ap_server_conf, child_slot);
1573                     --remaining_children_to_start;
1574                 }
1575 #if APR_HAS_OTHER_CHILD
1576             }
1577             else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH,
1578                                                 status) == 0) {
1579                 /* handled */
1580 #endif
1581             }
1582             else if (is_graceful) {
1583                 /* Great, we've probably just lost a slot in the
1584                  * scoreboard.  Somehow we don't know about this child.
1585                  */
1586                 ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
1587                              ap_server_conf,
1588                              "long lost child came home! (pid %ld)",
1589                              (long)pid.pid);
1590             }
1591             /* Don't perform idle maintenance when a child dies,
1592              * only do it when there's a timeout.  Remember only a
1593              * finite number of children can die, and it's pretty
1594              * pathological for a lot to die suddenly.
1595              */
1596             continue;
1597         }
1598         else if (remaining_children_to_start) {
1599             /* we hit a 1 second timeout in which none of the previous
1600              * generation of children needed to be reaped... so assume
1601              * they're all done, and pick up the slack if any is left.
1602              */
1603             startup_children(remaining_children_to_start);
1604             remaining_children_to_start = 0;
1605             /* In any event we really shouldn't do the code below because
1606              * few of the servers we just started are in the IDLE state
1607              * yet, so we'd mistakenly create an extra server.
1608              */
1609             continue;
1610         }
1611
1612         perform_idle_server_maintenance();
1613     }
1614 }
1615
1616 int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
1617 {
1618     int remaining_children_to_start;
1619     apr_status_t rv;
1620
1621     ap_log_pid(pconf, ap_pid_fname);
1622
1623     first_server_limit = server_limit;
1624     first_thread_limit = thread_limit;
1625     if (changed_limit_at_restart) {
1626         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
1627                      "WARNING: Attempt to change ServerLimit or ThreadLimit "
1628                      "ignored during restart");
1629         changed_limit_at_restart = 0;
1630     }
1631     
1632     /* Initialize cross-process accept lock */
1633     ap_lock_fname = apr_psprintf(_pconf, "%s.%" APR_PID_T_FMT,
1634                                  ap_server_root_relative(_pconf, ap_lock_fname),
1635                                  ap_my_pid);
1636
1637     rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname, 
1638                                ap_accept_lock_mech, _pconf);
1639     if (rv != APR_SUCCESS) {
1640         ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
1641                      "Couldn't create accept lock");
1642         mpm_state = AP_MPMQ_STOPPING;
1643         return 1;
1644     }
1645
1646 #if APR_USE_SYSVSEM_SERIALIZE
1647     if (ap_accept_lock_mech == APR_LOCK_DEFAULT || 
1648         ap_accept_lock_mech == APR_LOCK_SYSVSEM) {
1649 #else
1650     if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) {
1651 #endif
1652         rv = unixd_set_proc_mutex_perms(accept_mutex);
1653         if (rv != APR_SUCCESS) {
1654             ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
1655                          "Couldn't set permissions on cross-process lock; "
1656                          "check User and Group directives");
1657             mpm_state = AP_MPMQ_STOPPING;
1658             return 1;
1659         }
1660     }
1661
1662     if (!is_graceful) {
1663         if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
1664             mpm_state = AP_MPMQ_STOPPING;
1665             return 1;
1666         }
1667         /* fix the generation number in the global score; we just got a new,
1668          * cleared scoreboard
1669          */
1670         ap_scoreboard_image->global->running_generation = ap_my_generation;
1671     }
1672
1673     set_signals();
1674     /* Don't thrash... */
1675     if (max_spare_threads < min_spare_threads + ap_threads_per_child)
1676         max_spare_threads = min_spare_threads + ap_threads_per_child;
1677
1678     /* If we're doing a graceful_restart then we're going to see a lot
1679      * of children exiting immediately when we get into the main loop
1680      * below (because we just sent them AP_SIG_GRACEFUL).  This happens pretty
1681      * rapidly... and for each one that exits we'll start a new one until
1682      * we reach at least daemons_min_free.  But we may be permitted to
1683      * start more than that, so we'll just keep track of how many we're
1684      * supposed to start up without the 1 second penalty between each fork.
1685      */
1686     remaining_children_to_start = ap_daemons_to_start;
1687     if (remaining_children_to_start > ap_daemons_limit) {
1688         remaining_children_to_start = ap_daemons_limit;
1689     }
1690     if (!is_graceful) {
1691         startup_children(remaining_children_to_start);
1692         remaining_children_to_start = 0;
1693     }
1694     else {
1695         /* give the system some time to recover before kicking into
1696             * exponential mode */
1697         hold_off_on_exponential_spawning = 10;
1698     }
1699
1700     ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
1701                 "%s configured -- resuming normal operations",
1702                 ap_get_server_version());
1703     ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
1704                 "Server built: %s", ap_get_server_built());
1705 #ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH
1706     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1707                 "AcceptMutex: %s (default: %s)",
1708                 apr_proc_mutex_name(accept_mutex),
1709                 apr_proc_mutex_defname());
1710 #endif
1711     restart_pending = shutdown_pending = 0;
1712     mpm_state = AP_MPMQ_RUNNING;
1713     
1714     server_main_loop(remaining_children_to_start);
1715     mpm_state = AP_MPMQ_STOPPING;
1716
1717     if (shutdown_pending) {
1718         /* Time to gracefully shut down:
1719          * Kill child processes, tell them to call child_exit, etc...
1720          * (By "gracefully" we don't mean graceful in the same sense as 
1721          * "apachectl graceful" where we allow old connections to finish.)
1722          */
1723         ap_mpm_pod_killpg(pod, ap_daemons_limit, FALSE);
1724         ap_reclaim_child_processes(1);                /* Start with SIGTERM */
1725
1726         if (!child_fatal) {
1727             /* cleanup pid file on normal shutdown */
1728             const char *pidfile = NULL;
1729             pidfile = ap_server_root_relative (pconf, ap_pid_fname);
1730             if ( pidfile != NULL && unlink(pidfile) == 0)
1731                 ap_log_error(APLOG_MARK, APLOG_INFO, 0,
1732                              ap_server_conf,
1733                              "removed PID file %s (pid=%ld)",
1734                              pidfile, (long)getpid());
1735     
1736             ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,
1737                          ap_server_conf, "caught SIGTERM, shutting down");
1738         }
1739         return 1;
1740     }
1741
1742     /* we've been told to restart */
1743     apr_signal(SIGHUP, SIG_IGN);
1744
1745     if (one_process) {
1746         /* not worth thinking about */
1747         return 1;
1748     }
1749
1750     /* advance to the next generation */
1751     /* XXX: we really need to make sure this new generation number isn't in
1752      * use by any of the children.
1753      */
1754     ++ap_my_generation;
1755     ap_scoreboard_image->global->running_generation = ap_my_generation;
1756     
1757     if (is_graceful) {
1758         ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
1759                      AP_SIG_GRACEFUL_STRING " received.  Doing graceful restart");
1760         /* wake up the children...time to die.  But we'll have more soon */
1761         ap_mpm_pod_killpg(pod, ap_daemons_limit, TRUE);
1762     
1763
1764         /* This is mostly for debugging... so that we know what is still
1765          * gracefully dealing with existing request.
1766          */
1767         
1768     }
1769     else {
1770         /* Kill 'em all.  Since the child acts the same on the parents SIGTERM 
1771          * and a SIGHUP, we may as well use the same signal, because some user
1772          * pthreads are stealing signals from us left and right.
1773          */
1774         ap_mpm_pod_killpg(pod, ap_daemons_limit, FALSE);
1775
1776         ap_reclaim_child_processes(1);                /* Start with SIGTERM */
1777         ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
1778                     "SIGHUP received.  Attempting to restart");
1779     }
1780
1781     return 0;
1782 }
1783
1784 /* This really should be a post_config hook, but the error log is already
1785  * redirected by that point, so we need to do this in the open_logs phase.
1786  */
1787 static int worker_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
1788 {
1789     apr_status_t rv;
1790
1791     pconf = p;
1792     ap_server_conf = s;
1793
1794     if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {
1795         ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0,
1796                      NULL, "no listening sockets available, shutting down");
1797         return DONE;
1798     }
1799
1800     if (!one_process) {
1801         if ((rv = ap_mpm_pod_open(pconf, &pod))) {
1802             ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL,
1803                     "Could not open pipe-of-death.");
1804             return DONE;
1805         }
1806     }
1807     return OK;
1808 }
1809
1810 static int worker_pre_config(apr_pool_t *pconf, apr_pool_t *plog, 
1811                              apr_pool_t *ptemp)
1812 {
1813     static int restart_num = 0;
1814     int no_detach, debug, foreground;
1815     ap_directive_t *pdir;
1816     ap_directive_t *max_clients = NULL;
1817     apr_status_t rv;
1818
1819     mpm_state = AP_MPMQ_STARTING;
1820
1821     /* make sure that "ThreadsPerChild" gets set before "MaxClients" */
1822     for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) {
1823         if (strncasecmp(pdir->directive, "ThreadsPerChild", 15) == 0) {
1824             if (!max_clients) {
1825                 break; /* we're in the clear, got ThreadsPerChild first */
1826             }
1827             else {
1828                 /* now to swap the data */
1829                 ap_directive_t temp;
1830
1831                 temp.directive = pdir->directive;
1832                 temp.args = pdir->args;
1833                 /* Make sure you don't change 'next', or you may get loops! */
1834                 /* XXX: first_child, parent, and data can never be set
1835                  * for these directives, right? -aaron */
1836                 temp.filename = pdir->filename;
1837                 temp.line_num = pdir->line_num;
1838
1839                 pdir->directive = max_clients->directive;
1840                 pdir->args = max_clients->args;
1841                 pdir->filename = max_clients->filename;
1842                 pdir->line_num = max_clients->line_num;
1843                 
1844                 max_clients->directive = temp.directive;
1845                 max_clients->args = temp.args;
1846                 max_clients->filename = temp.filename;
1847                 max_clients->line_num = temp.line_num;
1848                 break;
1849             }
1850         }
1851         else if (!max_clients
1852                  && strncasecmp(pdir->directive, "MaxClients", 10) == 0) {
1853             max_clients = pdir;
1854         }
1855     }
1856
1857     debug = ap_exists_config_define("DEBUG");
1858
1859     if (debug) {
1860         foreground = one_process = 1;
1861         no_detach = 0;
1862     }
1863     else {
1864         one_process = ap_exists_config_define("ONE_PROCESS");
1865         no_detach = ap_exists_config_define("NO_DETACH");
1866         foreground = ap_exists_config_define("FOREGROUND");
1867     }
1868
1869     /* sigh, want this only the second time around */
1870     if (restart_num++ == 1) {
1871         is_graceful = 0;
1872
1873         if (!one_process && !foreground) {
1874             rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND
1875                                            : APR_PROC_DETACH_DAEMONIZE);
1876             if (rv != APR_SUCCESS) {
1877                 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,
1878                              "apr_proc_detach failed");
1879                 return HTTP_INTERNAL_SERVER_ERROR;
1880             }
1881         }
1882         parent_pid = ap_my_pid = getpid();
1883     }
1884
1885     unixd_pre_config(ptemp);
1886     ap_listen_pre_config();
1887     ap_daemons_to_start = DEFAULT_START_DAEMON;
1888     min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
1889     max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
1890     ap_daemons_limit = server_limit;
1891     ap_threads_per_child = DEFAULT_THREADS_PER_CHILD;
1892     ap_pid_fname = DEFAULT_PIDLOG;
1893     ap_lock_fname = DEFAULT_LOCKFILE;
1894     ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
1895     ap_extended_status = 0;
1896 #ifdef AP_MPM_WANT_SET_MAX_MEM_FREE
1897         ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED;
1898 #endif
1899
1900     apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir));
1901
1902     return OK;
1903 }
1904
1905 static void worker_hooks(apr_pool_t *p)
1906 {
1907     /* The worker open_logs phase must run before the core's, or stderr
1908      * will be redirected to a file, and the messages won't print to the
1909      * console.
1910      */
1911     static const char *const aszSucc[] = {"core.c", NULL};
1912     one_process = 0;
1913
1914     ap_hook_open_logs(worker_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE);
1915     /* we need to set the MPM state before other pre-config hooks use MPM query
1916      * to retrieve it, so register as REALLY_FIRST
1917      */
1918     ap_hook_pre_config(worker_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
1919 }
1920
1921 static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy,
1922                                         const char *arg) 
1923 {
1924     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1925     if (err != NULL) {
1926         return err;
1927     }
1928
1929     ap_daemons_to_start = atoi(arg);
1930     return NULL;
1931 }
1932
1933 static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy,
1934                                          const char *arg)
1935 {
1936     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1937     if (err != NULL) {
1938         return err;
1939     }
1940
1941     min_spare_threads = atoi(arg);
1942     if (min_spare_threads <= 0) {
1943        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1944                     "WARNING: detected MinSpareThreads set to non-positive.");
1945        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1946                     "Resetting to 1 to avoid almost certain Apache failure.");
1947        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1948                     "Please read the documentation.");
1949        min_spare_threads = 1;
1950     }
1951        
1952     return NULL;
1953 }
1954
1955 static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy,
1956                                          const char *arg)
1957 {
1958     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1959     if (err != NULL) {
1960         return err;
1961     }
1962
1963     max_spare_threads = atoi(arg);
1964     return NULL;
1965 }
1966
1967 static const char *set_max_clients (cmd_parms *cmd, void *dummy,
1968                                      const char *arg) 
1969 {
1970     int max_clients;
1971     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1972     if (err != NULL) {
1973         return err;
1974     }
1975
1976     /* It is ok to use ap_threads_per_child here because we are
1977      * sure that it gets set before MaxClients in the pre_config stage. */
1978     max_clients = atoi(arg);
1979     if (max_clients < ap_threads_per_child) {
1980        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1981                     "WARNING: MaxClients (%d) must be at least as large",
1982                     max_clients);
1983        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1984                     " as ThreadsPerChild (%d). Automatically",
1985                     ap_threads_per_child);
1986        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1987                     " increasing MaxClients to %d.",
1988                     ap_threads_per_child);
1989        max_clients = ap_threads_per_child;
1990     }
1991     ap_daemons_limit = max_clients / ap_threads_per_child;
1992     if ((max_clients > 0) && (max_clients % ap_threads_per_child)) {
1993        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1994                     "WARNING: MaxClients (%d) is not an integer multiple",
1995                     max_clients);
1996        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
1997                     " of ThreadsPerChild (%d), lowering MaxClients to %d",
1998                     ap_threads_per_child,
1999                     ap_daemons_limit * ap_threads_per_child);
2000        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
2001                     " for a maximum of %d child processes,",
2002                     ap_daemons_limit);
2003        max_clients = ap_daemons_limit * ap_threads_per_child; 
2004     }
2005     if (ap_daemons_limit > server_limit) {
2006        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
2007                     "WARNING: MaxClients of %d would require %d servers,",
2008                     max_clients, ap_daemons_limit);
2009        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
2010                     " and would exceed the ServerLimit value of %d.",
2011                     server_limit);
2012        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
2013                     " Automatically lowering MaxClients to %d.  To increase,",
2014                     server_limit * ap_threads_per_child);
2015        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
2016                     " please see the ServerLimit directive.");
2017        ap_daemons_limit = server_limit;
2018     } 
2019     else if (ap_daemons_limit < 1) {
2020         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
2021                      "WARNING: Require MaxClients > 0, setting to 1");
2022         ap_daemons_limit = 1;
2023     }
2024     return NULL;
2025 }
2026
2027 static const char *set_threads_per_child (cmd_parms *cmd, void *dummy,
2028                                           const char *arg) 
2029 {
2030     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2031     if (err != NULL) {
2032         return err;
2033     }
2034
2035     ap_threads_per_child = atoi(arg);
2036     if (ap_threads_per_child > thread_limit) {
2037         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
2038                      "WARNING: ThreadsPerChild of %d exceeds ThreadLimit "
2039                      "value of %d", ap_threads_per_child,
2040                      thread_limit);
2041         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
2042                      "threads, lowering ThreadsPerChild to %d. To increase, please"
2043                      " see the", thread_limit);
2044         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
2045                      " ThreadLimit directive.");
2046         ap_threads_per_child = thread_limit;
2047     }
2048     else if (ap_threads_per_child < 1) {
2049         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
2050                      "WARNING: Require ThreadsPerChild > 0, setting to 1");
2051         ap_threads_per_child = 1;
2052     }
2053     return NULL;
2054 }
2055
2056 static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) 
2057 {
2058     int tmp_server_limit;
2059     
2060     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2061     if (err != NULL) {
2062         return err;
2063     }
2064
2065     tmp_server_limit = atoi(arg);
2066     /* you cannot change ServerLimit across a restart; ignore
2067      * any such attempts
2068      */
2069     if (first_server_limit &&
2070         tmp_server_limit != server_limit) {
2071         /* how do we log a message?  the error log is a bit bucket at this
2072          * point; we'll just have to set a flag so that ap_mpm_run()
2073          * logs a warning later
2074          */
2075         changed_limit_at_restart = 1;
2076         return NULL;
2077     }
2078     server_limit = tmp_server_limit;
2079     
2080     if (server_limit > MAX_SERVER_LIMIT) {
2081        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
2082                     "WARNING: ServerLimit of %d exceeds compile time limit "
2083                     "of %d servers,", server_limit, MAX_SERVER_LIMIT);
2084        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
2085                     " lowering ServerLimit to %d.", MAX_SERVER_LIMIT);
2086        server_limit = MAX_SERVER_LIMIT;
2087     } 
2088     else if (server_limit < 1) {
2089         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
2090                      "WARNING: Require ServerLimit > 0, setting to 1");
2091         server_limit = 1;
2092     }
2093     return NULL;
2094 }
2095
2096 static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) 
2097 {
2098     int tmp_thread_limit;
2099     
2100     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2101     if (err != NULL) {
2102         return err;
2103     }
2104
2105     tmp_thread_limit = atoi(arg);
2106     /* you cannot change ThreadLimit across a restart; ignore
2107      * any such attempts
2108      */
2109     if (first_thread_limit &&
2110         tmp_thread_limit != thread_limit) {
2111         /* how do we log a message?  the error log is a bit bucket at this
2112          * point; we'll just have to set a flag so that ap_mpm_run()
2113          * logs a warning later
2114          */
2115         changed_limit_at_restart = 1;
2116         return NULL;
2117     }
2118     thread_limit = tmp_thread_limit;
2119     
2120     if (thread_limit > MAX_THREAD_LIMIT) {
2121        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
2122                     "WARNING: ThreadLimit of %d exceeds compile time limit "
2123                     "of %d servers,", thread_limit, MAX_THREAD_LIMIT);
2124        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
2125                     " lowering ThreadLimit to %d.", MAX_THREAD_LIMIT);
2126        thread_limit = MAX_THREAD_LIMIT;
2127     } 
2128     else if (thread_limit < 1) {
2129         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 
2130                      "WARNING: Require ThreadLimit > 0, setting to 1");
2131         thread_limit = 1;
2132     }
2133     return NULL;
2134 }
2135
2136 static const command_rec worker_cmds[] = {
2137 UNIX_DAEMON_COMMANDS,
2138 LISTEN_COMMANDS,
2139 AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
2140   "Number of child processes launched at server startup"),
2141 AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF,
2142   "Minimum number of idle threads, to handle request spikes"),
2143 AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF,
2144   "Maximum number of idle threads"),
2145 AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF,
2146   "Maximum number of threads alive at the same time"),
2147 AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF,
2148   "Number of threads each child creates"),
2149 AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF,
2150   "Maximum number of child processes for this run of Apache"),
2151 AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF,
2152   "Maximum number of worker threads per child process for this run of Apache - Upper limit for ThreadsPerChild"),
2153 { NULL }
2154 };
2155
2156 module AP_MODULE_DECLARE_DATA mpm_worker_module = {
2157     MPM20_MODULE_STUFF,
2158     ap_mpm_rewrite_args,        /* hook to run before apache parses args */
2159     NULL,                       /* create per-directory config structure */
2160     NULL,                       /* merge per-directory config structures */
2161     NULL,                       /* create per-server config structure */
2162     NULL,                       /* merge per-server config structures */
2163     worker_cmds,                /* command apr_table_t */
2164     worker_hooks                /* register_hooks */
2165 };
2166