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