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