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