]> granicus.if.org Git - apache/blob - server/mpm/event/event.c
mpm-query hook: distinguish between DECLINED and APR_ENOTIMPL so that
[apache] / server / mpm / event / event.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 /**
18  * This MPM tries to fix the 'keep alive problem' in HTTP.
19  *
20  * After a client completes the first request, the client can keep the
21  * connection open to send more requests with the same socket.  This can save
22  * signifigant overhead in creating TCP connections.  However, the major
23  * disadvantage is that Apache traditionally keeps an entire child
24  * process/thread waiting for data from the client.  To solve this problem,
25  * this MPM has a dedicated thread for handling both the Listenting sockets,
26  * and all sockets that are in a Keep Alive status.
27  *
28  * The MPM assumes the underlying apr_pollset implmentation is somewhat
29  * threadsafe.  This currently is only compatible with KQueue and EPoll.  This
30  * enables the MPM to avoid extra high level locking or having to wake up the
31  * listener thread when a keep-alive socket needs to be sent to it.
32  *
33  * This MPM not preform well on older platforms that do not have very good
34  * threading, like Linux with a 2.4 kernel, but this does not matter, since we
35  * require EPoll or KQueue.
36  *
37  * For FreeBSD, use 5.3.  It is possible to run this MPM on FreeBSD 5.2.1, if
38  * you use libkse (see `man libmap.conf`).
39  *
40  * For NetBSD, use at least 2.0.
41  *
42  * For Linux, you should use a 2.6 kernel, and make sure your glibc has epoll
43  * support compiled in.
44  *
45  */
46
47 #include "apr.h"
48 #include "apr_portable.h"
49 #include "apr_strings.h"
50 #include "apr_file_io.h"
51 #include "apr_thread_proc.h"
52 #include "apr_signal.h"
53 #include "apr_thread_mutex.h"
54 #include "apr_proc_mutex.h"
55 #include "apr_poll.h"
56 #include "apr_ring.h"
57 #include "apr_queue.h"
58 #define APR_WANT_STRFUNC
59 #include "apr_want.h"
60
61 #if APR_HAVE_UNISTD_H
62 #include <unistd.h>
63 #endif
64 #if APR_HAVE_SYS_SOCKET_H
65 #include <sys/socket.h>
66 #endif
67 #if APR_HAVE_SYS_WAIT_H
68 #include <sys/wait.h>
69 #endif
70 #ifdef HAVE_SYS_PROCESSOR_H
71 #include <sys/processor.h>      /* for bindprocessor() */
72 #endif
73
74 #if !APR_HAS_THREADS
75 #error The Event MPM requires APR threads, but they are unavailable.
76 #endif
77
78 #include "ap_config.h"
79 #include "httpd.h"
80 #include "http_main.h"
81 #include "http_log.h"
82 #include "http_config.h"        /* for read_config */
83 #include "http_core.h"          /* for get_remote_host */
84 #include "http_connection.h"
85 #include "ap_mpm.h"
86 #include "pod.h"
87 #include "mpm_common.h"
88 #include "ap_listen.h"
89 #include "scoreboard.h"
90 #include "fdqueue.h"
91 #include "mpm_default.h"
92 #include "http_vhost.h"
93 #include "unixd.h"
94
95 #include <signal.h>
96 #include <limits.h>             /* for INT_MAX */
97
98 #include "mod_serf.h"
99
100 #if AP_HAS_SERF
101 #include "serf.h"
102 #endif
103
104 /* Limit on the total --- clients will be locked out if more servers than
105  * this are needed.  It is intended solely to keep the server from crashing
106  * when things get out of hand.
107  *
108  * We keep a hard maximum number of servers, for two reasons --- first off,
109  * in case something goes seriously wrong, we want to stop the fork bomb
110  * short of actually crashing the machine we're running on by filling some
111  * kernel table.  Secondly, it keeps the size of the scoreboard file small
112  * enough that we can read the whole thing without worrying too much about
113  * the overhead.
114  */
115 #ifndef DEFAULT_SERVER_LIMIT
116 #define DEFAULT_SERVER_LIMIT 16
117 #endif
118
119 /* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT.  We want
120  * some sort of compile-time limit to help catch typos.
121  */
122 #ifndef MAX_SERVER_LIMIT
123 #define MAX_SERVER_LIMIT 20000
124 #endif
125
126 /* Limit on the threads per process.  Clients will be locked out if more than
127  * this are needed.
128  *
129  * We keep this for one reason it keeps the size of the scoreboard file small
130  * enough that we can read the whole thing without worrying too much about
131  * the overhead.
132  */
133 #ifndef DEFAULT_THREAD_LIMIT
134 #define DEFAULT_THREAD_LIMIT 64
135 #endif
136
137 /* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT.  We want
138  * some sort of compile-time limit to help catch typos.
139  */
140 #ifndef MAX_THREAD_LIMIT
141 #define MAX_THREAD_LIMIT 100000
142 #endif
143
144 #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
145
146 /*
147  * Actual definitions of config globals
148  */
149
150 static int threads_per_child = 0;   /* Worker threads per child */
151 static int ap_daemons_to_start = 0;
152 static int min_spare_threads = 0;
153 static int max_spare_threads = 0;
154 static int ap_daemons_limit = 0;
155 static int max_clients = 0;
156 static int server_limit = 0;
157 static int thread_limit = 0;
158 static int dying = 0;
159 static int workers_may_exit = 0;
160 static int start_thread_may_exit = 0;
161 static int listener_may_exit = 0;
162 static int requests_this_child;
163 static int num_listensocks = 0;
164 static int resource_shortage = 0;
165 static fd_queue_t *worker_queue;
166 static fd_queue_info_t *worker_queue_info;
167 static int mpm_state = AP_MPMQ_STARTING;
168 static int sick_child_detected;
169 static ap_generation_t volatile my_generation = 0;
170
171 static apr_thread_mutex_t *timeout_mutex;
172 APR_RING_HEAD(timeout_head_t, conn_state_t);
173 static struct timeout_head_t timeout_head, keepalive_timeout_head;
174
175 static apr_pollset_t *event_pollset;
176
177 #if AP_HAS_SERF
178 typedef struct {
179     apr_pollset_t *pollset;
180     apr_pool_t *pool;
181 } s_baton_t;
182
183 static serf_context_t *g_serf;
184 #endif
185
186 /* The structure used to pass unique initialization info to each thread */
187 typedef struct
188 {
189     int pid;
190     int tid;
191     int sd;
192 } proc_info;
193
194 /* Structure used to pass information to the thread responsible for
195  * creating the rest of the threads.
196  */
197 typedef struct
198 {
199     apr_thread_t **threads;
200     apr_thread_t *listener;
201     int child_num_arg;
202     apr_threadattr_t *threadattr;
203 } thread_starter;
204
205 typedef enum
206 {
207     PT_CSD,
208     PT_ACCEPT
209 #if AP_HAS_SERF
210     , PT_SERF
211 #endif
212 } poll_type_e;
213
214 typedef struct
215 {
216     poll_type_e type;
217     int bypass_push;
218     void *baton;
219 } listener_poll_type;
220
221 /* data retained by event across load/unload of the module
222  * allocated on first call to pre-config hook; located on
223  * subsequent calls to pre-config hook
224  */
225 typedef struct event_retained_data {
226     int first_server_limit;
227     int first_thread_limit;
228     int module_loads;
229 } event_retained_data;
230 static event_retained_data *retained;
231
232 #define ID_FROM_CHILD_THREAD(c, t)    ((c * thread_limit) + t)
233
234 /*
235  * The max child slot ever assigned, preserved across restarts.  Necessary
236  * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts.  We
237  * use this value to optimize routines that have to scan the entire
238  * scoreboard.
239  */
240 static int max_daemons_limit = -1;
241
242 static ap_event_pod_t *pod;
243
244 /* The event MPM respects a couple of runtime flags that can aid
245  * in debugging. Setting the -DNO_DETACH flag will prevent the root process
246  * from detaching from its controlling terminal. Additionally, setting
247  * the -DONE_PROCESS flag (which implies -DNO_DETACH) will get you the
248  * child_main loop running in the process which originally started up.
249  * This gives you a pretty nice debugging environment.  (You'll get a SIGHUP
250  * early in standalone_main; just continue through.  This is the server
251  * trying to kill off any child processes which it might have lying
252  * around --- Apache doesn't keep track of their pids, it just sends
253  * SIGHUP to the process group, ignoring it in the root process.
254  * Continue through and you'll be fine.).
255  */
256
257 static int one_process = 0;
258
259 #ifdef DEBUG_SIGSTOP
260 int raise_sigstop_flags;
261 #endif
262
263 static apr_pool_t *pconf;       /* Pool for config stuff */
264 static apr_pool_t *pchild;      /* Pool for httpd child stuff */
265
266 static pid_t ap_my_pid;         /* Linux getpid() doesn't work except in main
267                                    thread. Use this instead */
268 static pid_t parent_pid;
269 static apr_os_thread_t *listener_os_thread;
270
271 /* The LISTENER_SIGNAL signal will be sent from the main thread to the
272  * listener thread to wake it up for graceful termination (what a child
273  * process from an old generation does when the admin does "apachectl
274  * graceful").  This signal will be blocked in all threads of a child
275  * process except for the listener thread.
276  */
277 #define LISTENER_SIGNAL     SIGHUP
278
279 /* An array of socket descriptors in use by each thread used to
280  * perform a non-graceful (forced) shutdown of the server.
281  */
282 static apr_socket_t **worker_sockets;
283
284 static void close_worker_sockets(void)
285 {
286     int i;
287     for (i = 0; i < threads_per_child; i++) {
288         if (worker_sockets[i]) {
289             apr_socket_close(worker_sockets[i]);
290             worker_sockets[i] = NULL;
291         }
292     }
293 }
294
295 static void wakeup_listener(void)
296 {
297     listener_may_exit = 1;
298     if (!listener_os_thread) {
299         /* XXX there is an obscure path that this doesn't handle perfectly:
300          *     right after listener thread is created but before
301          *     listener_os_thread is set, the first worker thread hits an
302          *     error and starts graceful termination
303          */
304         return;
305     }
306
307     /* unblock the listener if it's waiting for a worker */
308     ap_queue_info_term(worker_queue_info); 
309
310     /*
311      * we should just be able to "kill(ap_my_pid, LISTENER_SIGNAL)" on all
312      * platforms and wake up the listener thread since it is the only thread
313      * with SIGHUP unblocked, but that doesn't work on Linux
314      */
315 #ifdef HAVE_PTHREAD_KILL
316     pthread_kill(*listener_os_thread, LISTENER_SIGNAL);
317 #else
318     kill(ap_my_pid, LISTENER_SIGNAL);
319 #endif
320 }
321
322 #define ST_INIT              0
323 #define ST_GRACEFUL          1
324 #define ST_UNGRACEFUL        2
325
326 static int terminate_mode = ST_INIT;
327
328 static void signal_threads(int mode)
329 {
330     if (terminate_mode == mode) {
331         return;
332     }
333     terminate_mode = mode;
334     mpm_state = AP_MPMQ_STOPPING;
335
336     /* in case we weren't called from the listener thread, wake up the
337      * listener thread
338      */
339     wakeup_listener();
340
341     /* for ungraceful termination, let the workers exit now;
342      * for graceful termination, the listener thread will notify the
343      * workers to exit once it has stopped accepting new connections
344      */
345     if (mode == ST_UNGRACEFUL) {
346         workers_may_exit = 1;
347         ap_queue_interrupt_all(worker_queue);
348         close_worker_sockets(); /* forcefully kill all current connections */
349     }
350 }
351
352 static int event_query(int query_code, int *result, apr_status_t *rv)
353 {
354     *rv = APR_SUCCESS;
355     switch (query_code) {
356     case AP_MPMQ_MAX_DAEMON_USED:
357         *result = max_daemons_limit;
358         break;
359     case AP_MPMQ_IS_THREADED:
360         *result = AP_MPMQ_STATIC;
361         break;
362     case AP_MPMQ_IS_FORKED:
363         *result = AP_MPMQ_DYNAMIC;
364         break;
365     case AP_MPMQ_IS_ASYNC:
366         *result = 1;
367         break;
368     case AP_MPMQ_HAS_SERF:
369         *result = 1;
370         break;
371     case AP_MPMQ_HARD_LIMIT_DAEMONS:
372         *result = server_limit;
373         break;
374     case AP_MPMQ_HARD_LIMIT_THREADS:
375         *result = thread_limit;
376         break;
377     case AP_MPMQ_MAX_THREADS:
378         *result = threads_per_child;
379         break;
380     case AP_MPMQ_MIN_SPARE_DAEMONS:
381         *result = 0;
382         break;
383     case AP_MPMQ_MIN_SPARE_THREADS:
384         *result = min_spare_threads;
385         break;
386     case AP_MPMQ_MAX_SPARE_DAEMONS:
387         *result = 0;
388         break;
389     case AP_MPMQ_MAX_SPARE_THREADS:
390         *result = max_spare_threads;
391         break;
392     case AP_MPMQ_MAX_REQUESTS_DAEMON:
393         *result = ap_max_requests_per_child;
394         break;
395     case AP_MPMQ_MAX_DAEMONS:
396         *result = ap_daemons_limit;
397         break;
398     case AP_MPMQ_MPM_STATE:
399         *result = mpm_state;
400         break;
401     case AP_MPMQ_GENERATION:
402         *result = my_generation;
403         break;
404     default:
405         *rv = APR_ENOTIMPL;
406         break;
407     }
408     return OK;
409 }
410
411 static apr_status_t event_note_child_killed(int childnum)
412 {
413     ap_scoreboard_image->parent[childnum].pid = 0;
414     return APR_SUCCESS;
415 }
416
417 static const char *event_get_name(void)
418 {
419     return "event";
420 }
421
422 /* a clean exit from a child with proper cleanup */
423 static void clean_child_exit(int code) __attribute__ ((noreturn));
424 static void clean_child_exit(int code)
425 {
426     mpm_state = AP_MPMQ_STOPPING;
427     if (pchild) {
428         apr_pool_destroy(pchild);
429     }
430     exit(code);
431 }
432
433 static void just_die(int sig)
434 {
435     clean_child_exit(0);
436 }
437
438 /*****************************************************************
439  * Connection structures and accounting...
440  */
441
442 /* volatile just in case */
443 static int volatile shutdown_pending;
444 static int volatile restart_pending;
445 static int volatile is_graceful;
446 static volatile int child_fatal;
447
448 /*
449  * ap_start_shutdown() and ap_start_restart(), below, are a first stab at
450  * functions to initiate shutdown or restart without relying on signals.
451  * Previously this was initiated in sig_term() and restart() signal handlers,
452  * but we want to be able to start a shutdown/restart from other sources --
453  * e.g. on Win32, from the service manager. Now the service manager can
454  * call ap_start_shutdown() or ap_start_restart() as appropiate.  Note that
455  * these functions can also be called by the child processes, since global
456  * variables are no longer used to pass on the required action to the parent.
457  *
458  * These should only be called from the parent process itself, since the
459  * parent process will use the shutdown_pending and restart_pending variables
460  * to determine whether to shutdown or restart. The child process should
461  * call signal_parent() directly to tell the parent to die -- this will
462  * cause neither of those variable to be set, which the parent will
463  * assume means something serious is wrong (which it will be, for the
464  * child to force an exit) and so do an exit anyway.
465  */
466
467 static void ap_start_shutdown(int graceful)
468 {
469     mpm_state = AP_MPMQ_STOPPING;
470     if (shutdown_pending == 1) {
471         /* Um, is this _probably_ not an error, if the user has
472          * tried to do a shutdown twice quickly, so we won't
473          * worry about reporting it.
474          */
475         return;
476     }
477     shutdown_pending = 1;
478     is_graceful = graceful;
479 }
480
481 /* do a graceful restart if graceful == 1 */
482 static void ap_start_restart(int graceful)
483 {
484     mpm_state = AP_MPMQ_STOPPING;
485     if (restart_pending == 1) {
486         /* Probably not an error - don't bother reporting it */
487         return;
488     }
489     restart_pending = 1;
490     is_graceful = graceful;
491 }
492
493 static void sig_term(int sig)
494 {
495     ap_start_shutdown(sig == AP_SIG_GRACEFUL_STOP);
496 }
497
498 static void restart(int sig)
499 {
500     ap_start_restart(sig == AP_SIG_GRACEFUL);
501 }
502
503 static void set_signals(void)
504 {
505 #ifndef NO_USE_SIGACTION
506     struct sigaction sa;
507 #endif
508
509     if (!one_process) {
510         ap_fatal_signal_setup(ap_server_conf, pconf);
511     }
512
513 #ifndef NO_USE_SIGACTION
514     sigemptyset(&sa.sa_mask);
515     sa.sa_flags = 0;
516
517     sa.sa_handler = sig_term;
518     if (sigaction(SIGTERM, &sa, NULL) < 0)
519         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
520                      "sigaction(SIGTERM)");
521 #ifdef AP_SIG_GRACEFUL_STOP
522     if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0)
523         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
524                      "sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")");
525 #endif
526 #ifdef SIGINT
527     if (sigaction(SIGINT, &sa, NULL) < 0)
528         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
529                      "sigaction(SIGINT)");
530 #endif
531 #ifdef SIGXCPU
532     sa.sa_handler = SIG_DFL;
533     if (sigaction(SIGXCPU, &sa, NULL) < 0)
534         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
535                      "sigaction(SIGXCPU)");
536 #endif
537 #ifdef SIGXFSZ
538     sa.sa_handler = SIG_DFL;
539     if (sigaction(SIGXFSZ, &sa, NULL) < 0)
540         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
541                      "sigaction(SIGXFSZ)");
542 #endif
543 #ifdef SIGPIPE
544     sa.sa_handler = SIG_IGN;
545     if (sigaction(SIGPIPE, &sa, NULL) < 0)
546         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
547                      "sigaction(SIGPIPE)");
548 #endif
549
550     /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy
551      * processing one */
552     sigaddset(&sa.sa_mask, SIGHUP);
553     sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL);
554     sa.sa_handler = restart;
555     if (sigaction(SIGHUP, &sa, NULL) < 0)
556         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
557                      "sigaction(SIGHUP)");
558     if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0)
559         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
560                      "sigaction(" AP_SIG_GRACEFUL_STRING ")");
561 #else
562     if (!one_process) {
563 #ifdef SIGXCPU
564         apr_signal(SIGXCPU, SIG_DFL);
565 #endif /* SIGXCPU */
566 #ifdef SIGXFSZ
567         apr_signal(SIGXFSZ, SIG_DFL);
568 #endif /* SIGXFSZ */
569     }
570
571     apr_signal(SIGTERM, sig_term);
572 #ifdef SIGHUP
573     apr_signal(SIGHUP, restart);
574 #endif /* SIGHUP */
575 #ifdef AP_SIG_GRACEFUL
576     apr_signal(AP_SIG_GRACEFUL, restart);
577 #endif /* AP_SIG_GRACEFUL */
578 #ifdef AP_SIG_GRACEFUL_STOP
579      apr_signal(AP_SIG_GRACEFUL_STOP, sig_term);
580 #endif /* AP_SIG_GRACEFUL_STOP */
581 #ifdef SIGPIPE
582     apr_signal(SIGPIPE, SIG_IGN);
583 #endif /* SIGPIPE */
584
585 #endif
586 }
587
588 /*****************************************************************
589  * Child process main loop.
590  */
591
592 static int process_socket(apr_thread_t *thd, apr_pool_t * p, apr_socket_t * sock,
593                           conn_state_t * cs, int my_child_num,
594                           int my_thread_num)
595 {
596     conn_rec *c;
597     listener_poll_type *pt;
598     long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num);
599     int rc;
600     ap_sb_handle_t *sbh;
601
602     ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num);
603
604     if (cs == NULL) {           /* This is a new connection */
605
606         cs = apr_pcalloc(p, sizeof(conn_state_t));
607
608         pt = apr_pcalloc(p, sizeof(*pt));
609
610         cs->bucket_alloc = apr_bucket_alloc_create(p);
611         c = ap_run_create_connection(p, ap_server_conf, sock,
612                                      conn_id, sbh, cs->bucket_alloc);
613         c->current_thread = thd;
614         cs->c = c;
615         c->cs = cs;
616         cs->p = p;
617         cs->pfd.desc_type = APR_POLL_SOCKET;
618         cs->pfd.reqevents = APR_POLLIN;
619         cs->pfd.desc.s = sock;
620         pt->type = PT_CSD;
621         pt->bypass_push = 1;
622         pt->baton = cs;
623         cs->pfd.client_data = pt;
624         APR_RING_ELEM_INIT(cs, timeout_list);
625
626         ap_update_vhost_given_ip(c);
627
628         rc = ap_run_pre_connection(c, sock);
629         if (rc != OK && rc != DONE) {
630             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
631                          "process_socket: connection aborted");
632             c->aborted = 1;
633         }
634
635         /**
636          * XXX If the platform does not have a usable way of bundling
637          * accept() with a socket readability check, like Win32,
638          * and there are measurable delays before the
639          * socket is readable due to the first data packet arriving,
640          * it might be better to create the cs on the listener thread
641          * with the state set to CONN_STATE_CHECK_REQUEST_LINE_READABLE
642          *
643          * FreeBSD users will want to enable the HTTP accept filter
644          * module in their kernel for the highest performance
645          * When the accept filter is active, sockets are kept in the
646          * kernel until a HTTP request is received.
647          */
648         cs->state = CONN_STATE_READ_REQUEST_LINE;
649
650     }
651     else {
652         c = cs->c;
653         c->sbh = sbh;
654         pt = cs->pfd.client_data;
655         c->current_thread = thd;
656     }
657
658     if (c->clogging_input_filters && !c->aborted) {
659         /* Since we have an input filter which 'cloggs' the input stream,
660          * like mod_ssl, lets just do the normal read from input filters,
661          * like the Worker MPM does.
662          */
663         ap_run_process_connection(c);
664         if (cs->state != CONN_STATE_SUSPENDED) {
665             cs->state = CONN_STATE_LINGER;
666         }
667     }
668
669 read_request:
670     if (cs->state == CONN_STATE_READ_REQUEST_LINE) {
671         if (!c->aborted) {
672             ap_run_process_connection(c);
673
674             /* state will be updated upon return
675              * fall thru to either wait for readability/timeout or
676              * do lingering close
677              */
678         }
679         else {
680             cs->state = CONN_STATE_LINGER;
681         }
682     }
683
684     if (cs->state == CONN_STATE_WRITE_COMPLETION) {
685         ap_filter_t *output_filter = c->output_filters;
686         apr_status_t rv;
687         while (output_filter->next != NULL) {
688             output_filter = output_filter->next;
689         }
690         rv = output_filter->frec->filter_func.out_func(output_filter, NULL);
691         if (rv != APR_SUCCESS) {
692             ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf,
693                      "network write failure in core output filter");
694             cs->state = CONN_STATE_LINGER;
695         }
696         else if (c->data_in_output_filters) {
697             /* Still in WRITE_COMPLETION_STATE:
698              * Set a write timeout for this connection, and let the
699              * event thread poll for writeability.
700              */
701             cs->expiration_time = ap_server_conf->timeout + apr_time_now();
702             apr_thread_mutex_lock(timeout_mutex);
703             APR_RING_INSERT_TAIL(&timeout_head, cs, conn_state_t, timeout_list);
704             apr_thread_mutex_unlock(timeout_mutex);
705             pt->bypass_push = 0;
706             cs->pfd.reqevents = APR_POLLOUT | APR_POLLHUP | APR_POLLERR;
707             rc = apr_pollset_add(event_pollset, &cs->pfd);
708             return 1;
709         }
710         else if (c->keepalive != AP_CONN_KEEPALIVE || c->aborted ||
711             listener_may_exit) {
712             c->cs->state = CONN_STATE_LINGER;
713         }
714         else if (c->data_in_input_filters) {
715             cs->state = CONN_STATE_READ_REQUEST_LINE;
716             goto read_request;
717         }
718         else {
719             cs->state = CONN_STATE_CHECK_REQUEST_LINE_READABLE;
720         }
721     }
722
723     if (cs->state == CONN_STATE_LINGER) {
724         ap_lingering_close(c);
725         apr_pool_clear(p);
726         ap_push_pool(worker_queue_info, p);
727         return 0;
728     }
729     else if (cs->state == CONN_STATE_CHECK_REQUEST_LINE_READABLE) {
730         apr_status_t rc;
731         listener_poll_type *pt = (listener_poll_type *) cs->pfd.client_data;
732
733         /* It greatly simplifies the logic to use a single timeout value here
734          * because the new element can just be added to the end of the list and
735          * it will stay sorted in expiration time sequence.  If brand new
736          * sockets are sent to the event thread for a readability check, this
737          * will be a slight behavior change - they use the non-keepalive
738          * timeout today.  With a normal client, the socket will be readable in
739          * a few milliseconds anyway.
740          */
741         cs->expiration_time = ap_server_conf->keep_alive_timeout +
742                               apr_time_now();
743         apr_thread_mutex_lock(timeout_mutex);
744         APR_RING_INSERT_TAIL(&keepalive_timeout_head, cs, conn_state_t, timeout_list);
745         apr_thread_mutex_unlock(timeout_mutex);
746
747         pt->bypass_push = 0;
748         /* Add work to pollset. */
749         cs->pfd.reqevents = APR_POLLIN;
750         rc = apr_pollset_add(event_pollset, &cs->pfd);
751
752         if (rc != APR_SUCCESS) {
753             ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
754                          "process_socket: apr_pollset_add failure");
755             AP_DEBUG_ASSERT(rc == APR_SUCCESS);
756         }
757     }
758     return 1;
759 }
760
761 /* requests_this_child has gone to zero or below.  See if the admin coded
762    "MaxRequestsPerChild 0", and keep going in that case.  Doing it this way
763    simplifies the hot path in worker_thread */
764 static void check_infinite_requests(void)
765 {
766     if (ap_max_requests_per_child) {
767         signal_threads(ST_GRACEFUL);
768     }
769     else {
770         /* wow! if you're executing this code, you may have set a record.
771          * either this child process has served over 2 billion requests, or
772          * you're running a threaded 2.0 on a 16 bit machine.
773          *
774          * I'll buy pizza and beers at Apachecon for the first person to do
775          * the former without cheating (dorking with INT_MAX, or running with
776          * uncommitted performance patches, for example).
777          *
778          * for the latter case, you probably deserve a beer too.   Greg Ames
779          */
780
781         requests_this_child = INT_MAX;  /* keep going */
782     }
783 }
784
785 static void unblock_signal(int sig)
786 {
787     sigset_t sig_mask;
788
789     sigemptyset(&sig_mask);
790     sigaddset(&sig_mask, sig);
791 #if defined(SIGPROCMASK_SETS_THREAD_MASK)
792     sigprocmask(SIG_UNBLOCK, &sig_mask, NULL);
793 #else
794     pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL);
795 #endif
796 }
797
798 static void dummy_signal_handler(int sig)
799 {
800     /* XXX If specifying SIG_IGN is guaranteed to unblock a syscall,
801      *     then we don't need this goofy function.
802      */
803 }
804
805
806 #if AP_HAS_SERF
807 static apr_status_t s_socket_add(void *user_baton,
808                                  apr_pollfd_t *pfd,
809                                  void *serf_baton)
810 {
811     s_baton_t *s = (s_baton_t*)user_baton;
812     /* XXXXX: recycle listener_poll_types */
813     listener_poll_type *pt = malloc(sizeof(*pt));
814     pt->type = PT_SERF;
815     pt->baton = serf_baton;
816     pfd->client_data = pt;
817     return apr_pollset_add(s->pollset, pfd);
818 }
819
820 static apr_status_t s_socket_remove(void *user_baton,
821                                     apr_pollfd_t *pfd,
822                                     void *serf_baton)
823 {
824     s_baton_t *s = (s_baton_t*)user_baton;
825     listener_poll_type *pt = pfd->client_data;
826     free(pt);
827     return apr_pollset_remove(s->pollset, pfd);
828 }
829 #endif
830
831 static apr_status_t init_pollset(apr_pool_t *p)
832 {
833 #if AP_HAS_SERF
834     s_baton_t *baton = NULL;
835 #endif
836     apr_status_t rv;
837     ap_listen_rec *lr;
838     listener_poll_type *pt;
839
840     rv = apr_thread_mutex_create(&timeout_mutex, APR_THREAD_MUTEX_DEFAULT, p);
841     if (rv != APR_SUCCESS) {
842         ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
843                      "creation of the timeout mutex failed.");
844         return rv;
845     }
846
847     APR_RING_INIT(&timeout_head, conn_state_t, timeout_list);
848     APR_RING_INIT(&keepalive_timeout_head, conn_state_t, timeout_list);
849
850     /* Create the main pollset */
851     rv = apr_pollset_create(&event_pollset,
852                             threads_per_child,
853                             p, APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY);
854     if (rv != APR_SUCCESS) {
855         ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
856                      "apr_pollset_create with Thread Safety failed.");
857         return rv;
858     }
859
860     for (lr = ap_listeners; lr != NULL; lr = lr->next) {
861         apr_pollfd_t *pfd = apr_palloc(p, sizeof(*pfd));
862         pt = apr_pcalloc(p, sizeof(*pt));
863         pfd->desc_type = APR_POLL_SOCKET;
864         pfd->desc.s = lr->sd;
865         pfd->reqevents = APR_POLLIN;
866
867         pt->type = PT_ACCEPT;
868         pt->baton = lr;
869
870         pfd->client_data = pt;
871
872         apr_socket_opt_set(pfd->desc.s, APR_SO_NONBLOCK, 1);
873         apr_pollset_add(event_pollset, pfd);
874
875         lr->accept_func = ap_unixd_accept;
876     }
877
878 #if AP_HAS_SERF
879     baton = apr_pcalloc(p, sizeof(*baton));
880     baton->pollset = event_pollset;
881     /* TODO: subpools, threads, reuse, etc.  -- currently use malloc() inside :( */
882     baton->pool = p;
883
884     g_serf = serf_context_create_ex(baton,
885                                     s_socket_add,
886                                     s_socket_remove, p);
887
888     ap_register_provider(p, "mpm_serf",
889                          "instance", "0", g_serf);
890
891 #endif
892
893     return APR_SUCCESS;
894 }
895
896 static apr_status_t push_timer2worker(timer_event_t* te)
897 {
898     return ap_queue_push_timer(worker_queue, te);
899 }
900
901 static apr_status_t push2worker(const apr_pollfd_t * pfd,
902                                 apr_pollset_t * pollset)
903 {
904     listener_poll_type *pt = (listener_poll_type *) pfd->client_data;
905     conn_state_t *cs = (conn_state_t *) pt->baton;
906     apr_status_t rc;
907
908     if (pt->bypass_push) {
909         return APR_SUCCESS;
910     }
911
912     pt->bypass_push = 1;
913
914     rc = apr_pollset_remove(pollset, pfd);
915
916     /*
917      * Some of the pollset backends, like KQueue or Epoll
918      * automagically remove the FD if the socket is closed,
919      * therefore, we can accept _SUCCESS or _NOTFOUND,
920      * and we still want to keep going
921      */
922     if (rc != APR_SUCCESS && !APR_STATUS_IS_NOTFOUND(rc)) {
923         cs->state = CONN_STATE_LINGER;
924     }
925
926     rc = ap_queue_push(worker_queue, cs->pfd.desc.s, cs, cs->p);
927     if (rc != APR_SUCCESS) {
928         /* trash the connection; we couldn't queue the connected
929          * socket to a worker
930          */
931         apr_bucket_alloc_destroy(cs->bucket_alloc);
932         apr_socket_close(cs->pfd.desc.s);
933         ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
934                      ap_server_conf, "push2worker: ap_queue_push failed");
935         apr_pool_clear(cs->p);
936         ap_push_pool(worker_queue_info, cs->p);
937     }
938
939     return rc;
940 }
941
942 /* get_worker:
943  *     reserve a worker thread, block if all are currently busy.
944  *     this prevents the worker queue from overflowing and lets
945  *     other processes accept new connections in the mean time.
946  */
947 static int get_worker(int *have_idle_worker_p)
948 {
949     apr_status_t rc;
950
951     if (!*have_idle_worker_p) {
952         rc = ap_queue_info_wait_for_idler(worker_queue_info);
953
954         if (rc == APR_SUCCESS) {
955             *have_idle_worker_p = 1;
956             return 1;
957         }
958         else {
959             if (!APR_STATUS_IS_EOF(rc)) {
960                 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
961                              "ap_queue_info_wait_for_idler failed.  "
962                              "Attempting to shutdown process gracefully");
963                 signal_threads(ST_GRACEFUL);
964             }
965             return 0;
966         }
967     }
968     else {
969         /* already reserved a worker thread - must have hit a
970          * transient error on a previous pass
971          */
972         return 1;
973     }
974 }
975
976 /* XXXXXX: Convert to skiplist or other better data structure 
977  * (yes, this is VERY VERY VERY VERY BAD)
978  */
979
980 /* Structures to reuse */
981 static APR_RING_HEAD(timer_free_ring_t, timer_event_t) timer_free_ring;
982 /* Active timers */
983 static APR_RING_HEAD(timer_ring_t, timer_event_t) timer_ring;
984
985 static apr_thread_mutex_t *g_timer_ring_mtx;
986
987 static apr_status_t event_register_timed_callback(apr_time_t t,
988                                                   ap_mpm_callback_fn_t *cbfn,
989                                                   void *baton)
990 {
991     int inserted = 0;
992     timer_event_t *ep;
993     timer_event_t *te;
994     /* oh yeah, and make locking smarter/fine grained. */
995     apr_thread_mutex_lock(g_timer_ring_mtx);
996
997     if (!APR_RING_EMPTY(&timer_free_ring, timer_event_t, link)) {
998         te = APR_RING_FIRST(&timer_free_ring);
999         APR_RING_REMOVE(te, link);
1000     }
1001     else {
1002         /* XXXXX: lol, pool allocation without a context from any thread.Yeah. Right. MPMs Suck. */
1003         te = malloc(sizeof(timer_event_t));
1004         APR_RING_ELEM_INIT(te, link);
1005     }
1006
1007     te->cbfunc = cbfn;
1008     te->baton = baton;
1009     /* XXXXX: optimize */
1010     te->when = t + apr_time_now();
1011
1012     /* Okay, insert sorted by when.. */
1013     for (ep = APR_RING_FIRST(&timer_ring);
1014          ep != APR_RING_SENTINEL(&timer_ring,
1015                                  timer_event_t, link);
1016          ep = APR_RING_NEXT(ep, link))
1017     {
1018         if (ep->when > te->when) {
1019             inserted = 1;
1020             APR_RING_INSERT_BEFORE(ep, te, link);
1021             break;
1022         }
1023     }
1024     
1025     if (!inserted) {
1026         APR_RING_INSERT_TAIL(&timer_ring, te, timer_event_t, link);
1027     }
1028
1029     apr_thread_mutex_unlock(g_timer_ring_mtx);
1030
1031     return APR_SUCCESS;
1032 }
1033
1034 #ifndef apr_time_from_msec
1035 #define apr_time_from_msec(x) (x * 1000)
1036 #endif
1037
1038 static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy)
1039 {
1040     timer_event_t *ep;
1041     timer_event_t *te;
1042     apr_status_t rc;
1043     proc_info *ti = dummy;
1044     int process_slot = ti->pid;
1045     apr_pool_t *tpool = apr_thread_pool_get(thd);
1046     void *csd = NULL;
1047     apr_pool_t *ptrans;         /* Pool for per-transaction stuff */
1048     ap_listen_rec *lr;
1049     int have_idle_worker = 0;
1050     conn_state_t *cs;
1051     const apr_pollfd_t *out_pfd;
1052     apr_int32_t num = 0;
1053     apr_time_t time_now = 0;
1054     apr_interval_time_t timeout_interval;
1055     apr_time_t timeout_time;
1056     listener_poll_type *pt;
1057
1058     free(ti);
1059
1060     /* the following times out events that are really close in the future
1061      *   to prevent extra poll calls
1062      *
1063      * current value is .1 second
1064      */
1065 #define TIMEOUT_FUDGE_FACTOR 100000
1066 #define EVENT_FUDGE_FACTOR 10000
1067
1068     rc = init_pollset(tpool);
1069     if (rc != APR_SUCCESS) {
1070         ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
1071                      "failed to initialize pollset, "
1072                      "attempting to shutdown process gracefully");
1073         signal_threads(ST_GRACEFUL);
1074         return NULL;
1075     }
1076
1077     /* Unblock the signal used to wake this thread up, and set a handler for
1078      * it.
1079      */
1080     unblock_signal(LISTENER_SIGNAL);
1081     apr_signal(LISTENER_SIGNAL, dummy_signal_handler);
1082
1083     while (!listener_may_exit) {
1084
1085         if (requests_this_child <= 0) {
1086             check_infinite_requests();
1087         }
1088
1089
1090         {
1091             apr_time_t now = apr_time_now();
1092             apr_thread_mutex_lock(g_timer_ring_mtx);
1093
1094             if (!APR_RING_EMPTY(&timer_ring, timer_event_t, link)) {
1095                 te = APR_RING_FIRST(&timer_ring);
1096                 if (te->when > now) {
1097                     timeout_interval = te->when - now;
1098                 }
1099                 else {
1100                     timeout_interval = 1;
1101                 }
1102             }
1103             else {
1104                 timeout_interval = apr_time_from_msec(100);
1105             }
1106             apr_thread_mutex_unlock(g_timer_ring_mtx);
1107         }
1108
1109 #if AP_HAS_SERF
1110         rc = serf_context_prerun(g_serf);
1111         if (rc != APR_SUCCESS) {
1112             /* TOOD: what should do here? ugh. */
1113         }
1114         
1115 #endif
1116         rc = apr_pollset_poll(event_pollset, timeout_interval, &num,
1117                               &out_pfd);
1118
1119         if (rc != APR_SUCCESS) {
1120             if (APR_STATUS_IS_EINTR(rc)) {
1121                 continue;
1122             }
1123             if (!APR_STATUS_IS_TIMEUP(rc)) {
1124                 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
1125                              "apr_pollset_poll failed.  Attempting to "
1126                              "shutdown process gracefully");
1127                 signal_threads(ST_GRACEFUL);
1128             }
1129         }
1130
1131         if (listener_may_exit)
1132             break;
1133
1134         {
1135             apr_time_t now = apr_time_now();
1136             apr_thread_mutex_lock(g_timer_ring_mtx);
1137             for (ep = APR_RING_FIRST(&timer_ring);
1138                  ep != APR_RING_SENTINEL(&timer_ring,
1139                                          timer_event_t, link);
1140                  ep = APR_RING_FIRST(&timer_ring))
1141             {
1142                 if (ep->when < now + EVENT_FUDGE_FACTOR) {
1143                     APR_RING_REMOVE(ep, link);
1144                     push_timer2worker(ep);
1145                 }
1146                 else {
1147                     break;
1148                 }
1149             }
1150             apr_thread_mutex_unlock(g_timer_ring_mtx);
1151         }
1152
1153         while (num && get_worker(&have_idle_worker)) {
1154             pt = (listener_poll_type *) out_pfd->client_data;
1155             if (pt->type == PT_CSD) {
1156                 /* one of the sockets is readable */
1157                 cs = (conn_state_t *) pt->baton;
1158                 switch (cs->state) {
1159                 case CONN_STATE_CHECK_REQUEST_LINE_READABLE:
1160                     cs->state = CONN_STATE_READ_REQUEST_LINE;
1161                     break;
1162                 case CONN_STATE_WRITE_COMPLETION:
1163                     break;
1164                 default:
1165                     ap_log_error(APLOG_MARK, APLOG_ERR, rc,
1166                                  ap_server_conf,
1167                                  "event_loop: unexpected state %d",
1168                                  cs->state);
1169                     AP_DEBUG_ASSERT(0);
1170                 }
1171
1172                 apr_thread_mutex_lock(timeout_mutex);
1173                 APR_RING_REMOVE(cs, timeout_list);
1174                 apr_thread_mutex_unlock(timeout_mutex);
1175                 APR_RING_ELEM_INIT(cs, timeout_list);
1176
1177                 rc = push2worker(out_pfd, event_pollset);
1178                 if (rc != APR_SUCCESS) {
1179                     ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1180                                  ap_server_conf, "push2worker failed");
1181                 }
1182                 else {
1183                     have_idle_worker = 0;
1184                 }
1185             }
1186             else if (pt->type == PT_ACCEPT) {
1187                 /* A Listener Socket is ready for an accept() */
1188
1189                 lr = (ap_listen_rec *) pt->baton;
1190
1191                 ap_pop_pool(&ptrans, worker_queue_info);
1192
1193                 if (ptrans == NULL) {
1194                     /* create a new transaction pool for each accepted socket */
1195                     apr_allocator_t *allocator;
1196
1197                     apr_allocator_create(&allocator);
1198                     apr_allocator_max_free_set(allocator,
1199                                                ap_max_mem_free);
1200                     apr_pool_create_ex(&ptrans, pconf, NULL, allocator);
1201                     apr_allocator_owner_set(allocator, ptrans);
1202                     if (ptrans == NULL) {
1203                         ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1204                                      ap_server_conf,
1205                                      "Failed to create transaction pool");
1206                         signal_threads(ST_GRACEFUL);
1207                         return NULL;
1208                     }
1209                 }
1210                 apr_pool_tag(ptrans, "transaction");
1211
1212                 rc = lr->accept_func(&csd, lr, ptrans);
1213
1214                 /* later we trash rv and rely on csd to indicate
1215                  * success/failure
1216                  */
1217                 AP_DEBUG_ASSERT(rc == APR_SUCCESS || !csd);
1218
1219                 if (rc == APR_EGENERAL) {
1220                     /* E[NM]FILE, ENOMEM, etc */
1221                     resource_shortage = 1;
1222                     signal_threads(ST_GRACEFUL);
1223                 }
1224
1225                 if (csd != NULL) {
1226                     rc = ap_queue_push(worker_queue, csd, NULL, ptrans);
1227                     if (rc != APR_SUCCESS) {
1228                         /* trash the connection; we couldn't queue the connected
1229                          * socket to a worker
1230                          */
1231                         apr_socket_close(csd);
1232                         ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1233                                      ap_server_conf,
1234                                      "ap_queue_push failed");
1235                         apr_pool_clear(ptrans);
1236                         ap_push_pool(worker_queue_info, ptrans);
1237                     }
1238                     else {
1239                         have_idle_worker = 0;
1240                     }
1241                 }
1242                 else {
1243                     apr_pool_clear(ptrans);
1244                     ap_push_pool(worker_queue_info, ptrans);
1245                 }
1246             }               /* if:else on pt->type */
1247 #if AP_HAS_SERF
1248             else if (pt->type == PT_SERF) {
1249                 /* send socket to serf. */
1250                 /* XXXX: this doesn't require get_worker(&have_idle_worker) */
1251                 serf_event_trigger(g_serf, pt->baton, out_pfd);
1252             }
1253 #endif
1254             out_pfd++;
1255             num--;
1256         }                   /* while for processing poll */
1257
1258         /* XXX possible optimization: stash the current time for use as
1259          * r->request_time for new requests
1260          */
1261         time_now = apr_time_now();
1262
1263         /* handle timed out sockets */
1264         apr_thread_mutex_lock(timeout_mutex);
1265
1266         /* Step 1: keepalive timeouts */
1267         cs = APR_RING_FIRST(&keepalive_timeout_head);
1268         timeout_time = time_now + TIMEOUT_FUDGE_FACTOR;
1269         while (!APR_RING_EMPTY(&keepalive_timeout_head, conn_state_t, timeout_list)
1270                && cs->expiration_time < timeout_time) {
1271
1272             cs->state = CONN_STATE_LINGER;
1273
1274             APR_RING_REMOVE(cs, timeout_list);
1275             apr_thread_mutex_unlock(timeout_mutex);
1276
1277             if (!get_worker(&have_idle_worker)) {
1278                 apr_thread_mutex_lock(timeout_mutex);
1279                 APR_RING_INSERT_HEAD(&keepalive_timeout_head, cs,
1280                                      conn_state_t, timeout_list);
1281                 break;
1282             }
1283
1284             rc = push2worker(&cs->pfd, event_pollset);
1285
1286             if (rc != APR_SUCCESS) {
1287                 return NULL;
1288                 /* XXX return NULL looks wrong - not an init failure
1289                  * that bypasses all the cleanup outside the main loop
1290                  * break seems more like it
1291                  * need to evaluate seriousness of push2worker failures
1292                  */
1293             }
1294             have_idle_worker = 0;
1295             apr_thread_mutex_lock(timeout_mutex);
1296             cs = APR_RING_FIRST(&keepalive_timeout_head);
1297         }
1298
1299         /* Step 2: write completion timeouts */
1300         cs = APR_RING_FIRST(&timeout_head);
1301         while (!APR_RING_EMPTY(&timeout_head, conn_state_t, timeout_list)
1302                && cs->expiration_time < timeout_time) {
1303
1304             cs->state = CONN_STATE_LINGER;
1305             APR_RING_REMOVE(cs, timeout_list);
1306             apr_thread_mutex_unlock(timeout_mutex);
1307
1308             if (!get_worker(&have_idle_worker)) {
1309                 apr_thread_mutex_lock(timeout_mutex);
1310                 APR_RING_INSERT_HEAD(&timeout_head, cs,
1311                                      conn_state_t, timeout_list);
1312                 break;
1313             }
1314
1315             rc = push2worker(&cs->pfd, event_pollset);
1316             if (rc != APR_SUCCESS) {
1317                 return NULL;
1318             }
1319             have_idle_worker = 0;
1320             apr_thread_mutex_lock(timeout_mutex);
1321             cs = APR_RING_FIRST(&timeout_head);
1322         }
1323
1324         apr_thread_mutex_unlock(timeout_mutex);
1325
1326     }     /* listener main loop */
1327
1328     ap_close_listeners();
1329     ap_queue_term(worker_queue);
1330     dying = 1;
1331     ap_scoreboard_image->parent[process_slot].quiescing = 1;
1332
1333     /* wake up the main thread */
1334     kill(ap_my_pid, SIGTERM);
1335
1336     apr_thread_exit(thd, APR_SUCCESS);
1337     return NULL;
1338 }
1339
1340 /* XXX For ungraceful termination/restart, we definitely don't want to
1341  *     wait for active connections to finish but we may want to wait
1342  *     for idle workers to get out of the queue code and release mutexes,
1343  *     since those mutexes are cleaned up pretty soon and some systems
1344  *     may not react favorably (i.e., segfault) if operations are attempted
1345  *     on cleaned-up mutexes.
1346  */
1347 static void *APR_THREAD_FUNC worker_thread(apr_thread_t * thd, void *dummy)
1348 {
1349     proc_info *ti = dummy;
1350     int process_slot = ti->pid;
1351     int thread_slot = ti->tid;
1352     apr_socket_t *csd = NULL;
1353     conn_state_t *cs;
1354     apr_pool_t *ptrans;         /* Pool for per-transaction stuff */
1355     apr_status_t rv;
1356     int is_idle = 0;
1357     timer_event_t *te = NULL;
1358     
1359     free(ti);
1360
1361     ap_scoreboard_image->servers[process_slot][thread_slot].pid = ap_my_pid;
1362     ap_scoreboard_image->servers[process_slot][thread_slot].tid = apr_os_thread_current();
1363     ap_scoreboard_image->servers[process_slot][thread_slot].generation = my_generation;
1364     ap_update_child_status_from_indexes(process_slot, thread_slot,
1365                                         SERVER_STARTING, NULL);
1366
1367     while (!workers_may_exit) {
1368         if (!is_idle) {
1369             rv = ap_queue_info_set_idle(worker_queue_info, NULL);
1370             if (rv != APR_SUCCESS) {
1371                 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
1372                              "ap_queue_info_set_idle failed. Attempting to "
1373                              "shutdown process gracefully.");
1374                 signal_threads(ST_GRACEFUL);
1375                 break;
1376             }
1377             is_idle = 1;
1378         }
1379
1380         ap_update_child_status_from_indexes(process_slot, thread_slot,
1381                                             SERVER_READY, NULL);
1382       worker_pop:
1383         if (workers_may_exit) {
1384             break;
1385         }
1386
1387         te = NULL;
1388         
1389         rv = ap_queue_pop_something(worker_queue, &csd, &cs, &ptrans, &te);
1390
1391         if (rv != APR_SUCCESS) {
1392             /* We get APR_EOF during a graceful shutdown once all the
1393              * connections accepted by this server process have been handled.
1394              */
1395             if (APR_STATUS_IS_EOF(rv)) {
1396                 break;
1397             }
1398             /* We get APR_EINTR whenever ap_queue_pop() has been interrupted
1399              * from an explicit call to ap_queue_interrupt_all(). This allows
1400              * us to unblock threads stuck in ap_queue_pop() when a shutdown
1401              * is pending.
1402              *
1403              * If workers_may_exit is set and this is ungraceful termination/
1404              * restart, we are bound to get an error on some systems (e.g.,
1405              * AIX, which sanity-checks mutex operations) since the queue
1406              * may have already been cleaned up.  Don't log the "error" if
1407              * workers_may_exit is set.
1408              */
1409             else if (APR_STATUS_IS_EINTR(rv)) {
1410                 goto worker_pop;
1411             }
1412             /* We got some other error. */
1413             else if (!workers_may_exit) {
1414                 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1415                              "ap_queue_pop failed");
1416             }
1417             continue;
1418         }
1419         if (te != NULL) {
1420             
1421             te->cbfunc(te->baton);
1422
1423             {
1424                 apr_thread_mutex_lock(g_timer_ring_mtx);
1425                 APR_RING_INSERT_TAIL(&timer_free_ring, te, timer_event_t, link);
1426                 apr_thread_mutex_unlock(g_timer_ring_mtx);
1427             }
1428         }
1429         else {
1430             is_idle = 0;
1431             worker_sockets[thread_slot] = csd;
1432             rv = process_socket(thd, ptrans, csd, cs, process_slot, thread_slot);
1433             if (!rv) {
1434                 requests_this_child--;
1435             }
1436             worker_sockets[thread_slot] = NULL;
1437         }
1438     }
1439
1440     ap_update_child_status_from_indexes(process_slot, thread_slot,
1441                                         (dying) ? SERVER_DEAD :
1442                                         SERVER_GRACEFUL,
1443                                         (request_rec *) NULL);
1444
1445     apr_thread_exit(thd, APR_SUCCESS);
1446     return NULL;
1447 }
1448
1449 static int check_signal(int signum)
1450 {
1451     switch (signum) {
1452     case SIGTERM:
1453     case SIGINT:
1454         return 1;
1455     }
1456     return 0;
1457 }
1458
1459
1460
1461 static void create_listener_thread(thread_starter * ts)
1462 {
1463     int my_child_num = ts->child_num_arg;
1464     apr_threadattr_t *thread_attr = ts->threadattr;
1465     proc_info *my_info;
1466     apr_status_t rv;
1467
1468     my_info = (proc_info *) malloc(sizeof(proc_info));
1469     my_info->pid = my_child_num;
1470     my_info->tid = -1;          /* listener thread doesn't have a thread slot */
1471     my_info->sd = 0;
1472     rv = apr_thread_create(&ts->listener, thread_attr, listener_thread,
1473                            my_info, pchild);
1474     if (rv != APR_SUCCESS) {
1475         ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1476                      "apr_thread_create: unable to create listener thread");
1477         /* let the parent decide how bad this really is */
1478         clean_child_exit(APEXIT_CHILDSICK);
1479     }
1480     apr_os_thread_get(&listener_os_thread, ts->listener);
1481 }
1482
1483 /* XXX under some circumstances not understood, children can get stuck
1484  *     in start_threads forever trying to take over slots which will
1485  *     never be cleaned up; for now there is an APLOG_DEBUG message issued
1486  *     every so often when this condition occurs
1487  */
1488 static void *APR_THREAD_FUNC start_threads(apr_thread_t * thd, void *dummy)
1489 {
1490     thread_starter *ts = dummy;
1491     apr_thread_t **threads = ts->threads;
1492     apr_threadattr_t *thread_attr = ts->threadattr;
1493     int child_num_arg = ts->child_num_arg;
1494     int my_child_num = child_num_arg;
1495     proc_info *my_info;
1496     apr_status_t rv;
1497     int i;
1498     int threads_created = 0;
1499     int listener_started = 0;
1500     int loops;
1501     int prev_threads_created;
1502
1503     /* We must create the fd queues before we start up the listener
1504      * and worker threads. */
1505     worker_queue = apr_pcalloc(pchild, sizeof(*worker_queue));
1506     rv = ap_queue_init(worker_queue, threads_per_child, pchild);
1507     if (rv != APR_SUCCESS) {
1508         ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1509                      "ap_queue_init() failed");
1510         clean_child_exit(APEXIT_CHILDFATAL);
1511     }
1512
1513     rv = ap_queue_info_create(&worker_queue_info, pchild,
1514                               threads_per_child);
1515     if (rv != APR_SUCCESS) {
1516         ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1517                      "ap_queue_info_create() failed");
1518         clean_child_exit(APEXIT_CHILDFATAL);
1519     }
1520
1521     worker_sockets = apr_pcalloc(pchild, threads_per_child
1522                                  * sizeof(apr_socket_t *));
1523
1524     loops = prev_threads_created = 0;
1525     while (1) {
1526         /* threads_per_child does not include the listener thread */
1527         for (i = 0; i < threads_per_child; i++) {
1528             int status =
1529                 ap_scoreboard_image->servers[child_num_arg][i].status;
1530
1531             if (status != SERVER_GRACEFUL && status != SERVER_DEAD) {
1532                 continue;
1533             }
1534
1535             my_info = (proc_info *) malloc(sizeof(proc_info));
1536             if (my_info == NULL) {
1537                 ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf,
1538                              "malloc: out of memory");
1539                 clean_child_exit(APEXIT_CHILDFATAL);
1540             }
1541             my_info->pid = my_child_num;
1542             my_info->tid = i;
1543             my_info->sd = 0;
1544
1545             /* We are creating threads right now */
1546             ap_update_child_status_from_indexes(my_child_num, i,
1547                                                 SERVER_STARTING, NULL);
1548             /* We let each thread update its own scoreboard entry.  This is
1549              * done because it lets us deal with tid better.
1550              */
1551             rv = apr_thread_create(&threads[i], thread_attr,
1552                                    worker_thread, my_info, pchild);
1553             if (rv != APR_SUCCESS) {
1554                 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1555                              "apr_thread_create: unable to create worker thread");
1556                 /* let the parent decide how bad this really is */
1557                 clean_child_exit(APEXIT_CHILDSICK);
1558             }
1559             threads_created++;
1560         }
1561
1562         /* Start the listener only when there are workers available */
1563         if (!listener_started && threads_created) {
1564             create_listener_thread(ts);
1565             listener_started = 1;
1566         }
1567
1568
1569         if (start_thread_may_exit || threads_created == threads_per_child) {
1570             break;
1571         }
1572         /* wait for previous generation to clean up an entry */
1573         apr_sleep(apr_time_from_sec(1));
1574         ++loops;
1575         if (loops % 120 == 0) { /* every couple of minutes */
1576             if (prev_threads_created == threads_created) {
1577                 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1578                              "child %" APR_PID_T_FMT " isn't taking over "
1579                              "slots very quickly (%d of %d)",
1580                              ap_my_pid, threads_created,
1581                              threads_per_child);
1582             }
1583             prev_threads_created = threads_created;
1584         }
1585     }
1586
1587     /* What state should this child_main process be listed as in the
1588      * scoreboard...?
1589      *  ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING,
1590      *                                      (request_rec *) NULL);
1591      *
1592      *  This state should be listed separately in the scoreboard, in some kind
1593      *  of process_status, not mixed in with the worker threads' status.
1594      *  "life_status" is almost right, but it's in the worker's structure, and
1595      *  the name could be clearer.   gla
1596      */
1597     apr_thread_exit(thd, APR_SUCCESS);
1598     return NULL;
1599 }
1600
1601 static void join_workers(apr_thread_t * listener, apr_thread_t ** threads)
1602 {
1603     int i;
1604     apr_status_t rv, thread_rv;
1605
1606     if (listener) {
1607         int iter;
1608
1609         /* deal with a rare timing window which affects waking up the
1610          * listener thread...  if the signal sent to the listener thread
1611          * is delivered between the time it verifies that the
1612          * listener_may_exit flag is clear and the time it enters a
1613          * blocking syscall, the signal didn't do any good...  work around
1614          * that by sleeping briefly and sending it again
1615          */
1616
1617         iter = 0;
1618         while (iter < 10 &&
1619 #ifdef HAVE_PTHREAD_KILL
1620                pthread_kill(*listener_os_thread, 0)
1621 #else
1622                kill(ap_my_pid, 0)
1623 #endif
1624                == 0) {
1625             /* listener not dead yet */
1626             apr_sleep(apr_time_make(0, 500000));
1627             wakeup_listener();
1628             ++iter;
1629         }
1630         if (iter >= 10) {
1631             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1632                          "the listener thread didn't exit");
1633         }
1634         else {
1635             rv = apr_thread_join(&thread_rv, listener);
1636             if (rv != APR_SUCCESS) {
1637                 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1638                              "apr_thread_join: unable to join listener thread");
1639             }
1640         }
1641     }
1642
1643     for (i = 0; i < threads_per_child; i++) {
1644         if (threads[i]) {       /* if we ever created this thread */
1645             rv = apr_thread_join(&thread_rv, threads[i]);
1646             if (rv != APR_SUCCESS) {
1647                 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1648                              "apr_thread_join: unable to join worker "
1649                              "thread %d", i);
1650             }
1651         }
1652     }
1653 }
1654
1655 static void join_start_thread(apr_thread_t * start_thread_id)
1656 {
1657     apr_status_t rv, thread_rv;
1658
1659     start_thread_may_exit = 1;  /* tell it to give up in case it is still
1660                                  * trying to take over slots from a
1661                                  * previous generation
1662                                  */
1663     rv = apr_thread_join(&thread_rv, start_thread_id);
1664     if (rv != APR_SUCCESS) {
1665         ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1666                      "apr_thread_join: unable to join the start " "thread");
1667     }
1668 }
1669
1670 static void child_main(int child_num_arg)
1671 {
1672     apr_thread_t **threads;
1673     apr_status_t rv;
1674     thread_starter *ts;
1675     apr_threadattr_t *thread_attr;
1676     apr_thread_t *start_thread_id;
1677
1678     mpm_state = AP_MPMQ_STARTING;       /* for benefit of any hooks that run as this
1679                                          * child initializes
1680                                          */
1681     ap_my_pid = getpid();
1682     ap_fatal_signal_child_setup(ap_server_conf);
1683     apr_pool_create(&pchild, pconf);
1684
1685     /*stuff to do before we switch id's, so we have permissions. */
1686     ap_reopen_scoreboard(pchild, NULL, 0);
1687
1688     if (ap_run_drop_privileges(pchild, ap_server_conf)) {
1689         clean_child_exit(APEXIT_CHILDFATAL);
1690     }
1691
1692     apr_thread_mutex_create(&g_timer_ring_mtx, APR_THREAD_MUTEX_DEFAULT, pchild);
1693     APR_RING_INIT(&timer_free_ring, timer_event_t, link);
1694     APR_RING_INIT(&timer_ring, timer_event_t, link);
1695     
1696     ap_run_child_init(pchild, ap_server_conf);
1697
1698     /* done with init critical section */
1699
1700     /* Just use the standard apr_setup_signal_thread to block all signals
1701      * from being received.  The child processes no longer use signals for
1702      * any communication with the parent process.
1703      */
1704     rv = apr_setup_signal_thread();
1705     if (rv != APR_SUCCESS) {
1706         ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
1707                      "Couldn't initialize signal thread");
1708         clean_child_exit(APEXIT_CHILDFATAL);
1709     }
1710
1711     if (ap_max_requests_per_child) {
1712         requests_this_child = ap_max_requests_per_child;
1713     }
1714     else {
1715         /* coding a value of zero means infinity */
1716         requests_this_child = INT_MAX;
1717     }
1718
1719     /* Setup worker threads */
1720
1721     /* clear the storage; we may not create all our threads immediately,
1722      * and we want a 0 entry to indicate a thread which was not created
1723      */
1724     threads = (apr_thread_t **) calloc(1,
1725                                        sizeof(apr_thread_t *) *
1726                                        threads_per_child);
1727     if (threads == NULL) {
1728         ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf,
1729                      "malloc: out of memory");
1730         clean_child_exit(APEXIT_CHILDFATAL);
1731     }
1732
1733     ts = (thread_starter *) apr_palloc(pchild, sizeof(*ts));
1734
1735     apr_threadattr_create(&thread_attr, pchild);
1736     /* 0 means PTHREAD_CREATE_JOINABLE */
1737     apr_threadattr_detach_set(thread_attr, 0);
1738
1739     if (ap_thread_stacksize != 0) {
1740         apr_threadattr_stacksize_set(thread_attr, ap_thread_stacksize);
1741     }
1742
1743     ts->threads = threads;
1744     ts->listener = NULL;
1745     ts->child_num_arg = child_num_arg;
1746     ts->threadattr = thread_attr;
1747
1748     rv = apr_thread_create(&start_thread_id, thread_attr, start_threads,
1749                            ts, pchild);
1750     if (rv != APR_SUCCESS) {
1751         ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1752                      "apr_thread_create: unable to create worker thread");
1753         /* let the parent decide how bad this really is */
1754         clean_child_exit(APEXIT_CHILDSICK);
1755     }
1756
1757     mpm_state = AP_MPMQ_RUNNING;
1758
1759     /* If we are only running in one_process mode, we will want to
1760      * still handle signals. */
1761     if (one_process) {
1762         /* Block until we get a terminating signal. */
1763         apr_signal_thread(check_signal);
1764         /* make sure the start thread has finished; signal_threads()
1765          * and join_workers() depend on that
1766          */
1767         /* XXX join_start_thread() won't be awakened if one of our
1768          *     threads encounters a critical error and attempts to
1769          *     shutdown this child
1770          */
1771         join_start_thread(start_thread_id);
1772
1773         /* helps us terminate a little more quickly than the dispatch of the
1774          * signal thread; beats the Pipe of Death and the browsers
1775          */
1776         signal_threads(ST_UNGRACEFUL);
1777
1778         /* A terminating signal was received. Now join each of the
1779          * workers to clean them up.
1780          *   If the worker already exited, then the join frees
1781          *   their resources and returns.
1782          *   If the worker hasn't exited, then this blocks until
1783          *   they have (then cleans up).
1784          */
1785         join_workers(ts->listener, threads);
1786     }
1787     else {                      /* !one_process */
1788         /* remove SIGTERM from the set of blocked signals...  if one of
1789          * the other threads in the process needs to take us down
1790          * (e.g., for MaxRequestsPerChild) it will send us SIGTERM
1791          */
1792         unblock_signal(SIGTERM);
1793         apr_signal(SIGTERM, dummy_signal_handler);
1794         /* Watch for any messages from the parent over the POD */
1795         while (1) {
1796             rv = ap_event_pod_check(pod);
1797             if (rv == AP_NORESTART) {
1798                 /* see if termination was triggered while we slept */
1799                 switch (terminate_mode) {
1800                 case ST_GRACEFUL:
1801                     rv = AP_GRACEFUL;
1802                     break;
1803                 case ST_UNGRACEFUL:
1804                     rv = AP_RESTART;
1805                     break;
1806                 }
1807             }
1808             if (rv == AP_GRACEFUL || rv == AP_RESTART) {
1809                 /* make sure the start thread has finished;
1810                  * signal_threads() and join_workers depend on that
1811                  */
1812                 join_start_thread(start_thread_id);
1813                 signal_threads(rv ==
1814                                AP_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL);
1815                 break;
1816             }
1817         }
1818
1819         /* A terminating signal was received. Now join each of the
1820          * workers to clean them up.
1821          *   If the worker already exited, then the join frees
1822          *   their resources and returns.
1823          *   If the worker hasn't exited, then this blocks until
1824          *   they have (then cleans up).
1825          */
1826         join_workers(ts->listener, threads);
1827     }
1828
1829     free(threads);
1830
1831     clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0);
1832 }
1833
1834 static int make_child(server_rec * s, int slot)
1835 {
1836     int pid;
1837
1838     if (slot + 1 > max_daemons_limit) {
1839         max_daemons_limit = slot + 1;
1840     }
1841
1842     if (one_process) {
1843         set_signals();
1844         ap_scoreboard_image->parent[slot].pid = getpid();
1845         child_main(slot);
1846     }
1847
1848     if ((pid = fork()) == -1) {
1849         ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
1850                      "fork: Unable to fork new process");
1851
1852         /* fork didn't succeed.  There's no need to touch the scoreboard;
1853          * if we were trying to replace a failed child process, then
1854          * server_main_loop() marked its workers SERVER_DEAD, and if
1855          * we were trying to replace a child process that exited normally,
1856          * its worker_thread()s left SERVER_DEAD or SERVER_GRACEFUL behind.
1857          */
1858
1859         /* In case system resources are maxxed out, we don't want
1860            Apache running away with the CPU trying to fork over and
1861            over and over again. */
1862         apr_sleep(apr_time_from_sec(10));
1863
1864         return -1;
1865     }
1866
1867     if (!pid) {
1868 #ifdef HAVE_BINDPROCESSOR
1869         /* By default, AIX binds to a single processor.  This bit unbinds
1870          * children which will then bind to another CPU.
1871          */
1872         int status = bindprocessor(BINDPROCESS, (int) getpid(),
1873                                    PROCESSOR_CLASS_ANY);
1874         if (status != OK)
1875             ap_log_error(APLOG_MARK, APLOG_WARNING, errno,
1876                          ap_server_conf,
1877                          "processor unbind failed %d", status);
1878 #endif
1879         RAISE_SIGSTOP(MAKE_CHILD);
1880
1881         apr_signal(SIGTERM, just_die);
1882         child_main(slot);
1883
1884         clean_child_exit(0);
1885     }
1886     /* else */
1887     if (ap_scoreboard_image->parent[slot].pid != 0) {
1888         /* This new child process is squatting on the scoreboard
1889          * entry owned by an exiting child process, which cannot
1890          * exit until all active requests complete.
1891          * Don't forget about this exiting child process, or we
1892          * won't be able to kill it if it doesn't exit by the
1893          * time the server is shut down.
1894          */
1895         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1896                      "taking over scoreboard slot from %" APR_PID_T_FMT "%s",
1897                      ap_scoreboard_image->parent[slot].pid,
1898                      ap_scoreboard_image->parent[slot].quiescing ?
1899                          " (quiescing)" : "");
1900         ap_register_extra_mpm_process(ap_scoreboard_image->parent[slot].pid);
1901     }
1902     ap_scoreboard_image->parent[slot].quiescing = 0;
1903     ap_scoreboard_image->parent[slot].pid = pid;
1904     return 0;
1905 }
1906
1907 /* start up a bunch of children */
1908 static void startup_children(int number_to_start)
1909 {
1910     int i;
1911
1912     for (i = 0; number_to_start && i < ap_daemons_limit; ++i) {
1913         if (ap_scoreboard_image->parent[i].pid != 0) {
1914             continue;
1915         }
1916         if (make_child(ap_server_conf, i) < 0) {
1917             break;
1918         }
1919         --number_to_start;
1920     }
1921 }
1922
1923
1924 /*
1925  * idle_spawn_rate is the number of children that will be spawned on the
1926  * next maintenance cycle if there aren't enough idle servers.  It is
1927  * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
1928  * without the need to spawn.
1929  */
1930 static int idle_spawn_rate = 1;
1931 #ifndef MAX_SPAWN_RATE
1932 #define MAX_SPAWN_RATE        (32)
1933 #endif
1934 static int hold_off_on_exponential_spawning;
1935
1936 static void perform_idle_server_maintenance(void)
1937 {
1938     int i, j;
1939     int idle_thread_count;
1940     worker_score *ws;
1941     process_score *ps;
1942     int free_length;
1943     int totally_free_length = 0;
1944     int free_slots[MAX_SPAWN_RATE];
1945     int last_non_dead;
1946     int total_non_dead;
1947     int active_thread_count = 0;
1948
1949     /* initialize the free_list */
1950     free_length = 0;
1951
1952     idle_thread_count = 0;
1953     last_non_dead = -1;
1954     total_non_dead = 0;
1955
1956     for (i = 0; i < ap_daemons_limit; ++i) {
1957         /* Initialization to satisfy the compiler. It doesn't know
1958          * that threads_per_child is always > 0 */
1959         int status = SERVER_DEAD;
1960         int any_dying_threads = 0;
1961         int any_dead_threads = 0;
1962         int all_dead_threads = 1;
1963
1964         if (i >= max_daemons_limit
1965             && totally_free_length == idle_spawn_rate)
1966             /* short cut if all active processes have been examined and
1967              * enough empty scoreboard slots have been found
1968              */
1969         
1970             break;
1971         ps = &ap_scoreboard_image->parent[i];
1972         for (j = 0; j < threads_per_child; j++) {
1973             ws = &ap_scoreboard_image->servers[i][j];
1974             status = ws->status;
1975
1976             /* XXX any_dying_threads is probably no longer needed    GLA */
1977             any_dying_threads = any_dying_threads ||
1978                 (status == SERVER_GRACEFUL);
1979             any_dead_threads = any_dead_threads || (status == SERVER_DEAD);
1980             all_dead_threads = all_dead_threads &&
1981                 (status == SERVER_DEAD || status == SERVER_GRACEFUL);
1982
1983             /* We consider a starting server as idle because we started it
1984              * at least a cycle ago, and if it still hasn't finished starting
1985              * then we're just going to swamp things worse by forking more.
1986              * So we hopefully won't need to fork more if we count it.
1987              * This depends on the ordering of SERVER_READY and SERVER_STARTING.
1988              */
1989             if (ps->pid != 0) { /* XXX just set all_dead_threads in outer
1990                                    for loop if no pid?  not much else matters */
1991                 if (status <= SERVER_READY &&
1992                         !ps->quiescing && ps->generation == my_generation) {
1993                     ++idle_thread_count;
1994                 }
1995                 if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
1996                     ++active_thread_count;
1997                 }
1998             }
1999         }
2000         if (any_dead_threads
2001             && totally_free_length < idle_spawn_rate
2002             && free_length < MAX_SPAWN_RATE
2003             && (!ps->pid      /* no process in the slot */
2004                   || ps->quiescing)) {  /* or at least one is going away */
2005             if (all_dead_threads) {
2006                 /* great! we prefer these, because the new process can
2007                  * start more threads sooner.  So prioritize this slot
2008                  * by putting it ahead of any slots with active threads.
2009                  *
2010                  * first, make room by moving a slot that's potentially still
2011                  * in use to the end of the array
2012                  */
2013                 free_slots[free_length] = free_slots[totally_free_length];
2014                 free_slots[totally_free_length++] = i;
2015             }
2016             else {
2017                 /* slot is still in use - back of the bus
2018                  */
2019                 free_slots[free_length] = i;
2020             }
2021             ++free_length;
2022         }
2023         /* XXX if (!ps->quiescing)     is probably more reliable  GLA */
2024         if (!any_dying_threads) {
2025             last_non_dead = i;
2026             ++total_non_dead;
2027         }
2028     }
2029
2030     if (sick_child_detected) {
2031         if (active_thread_count > 0) {
2032             /* some child processes appear to be working.  don't kill the
2033              * whole server.
2034              */
2035             sick_child_detected = 0;
2036         }
2037         else {
2038             /* looks like a basket case.  give up.
2039              */
2040             shutdown_pending = 1;
2041             child_fatal = 1;
2042             ap_log_error(APLOG_MARK, APLOG_ALERT, 0,
2043                          ap_server_conf,
2044                          "No active workers found..."
2045                          " Apache is exiting!");
2046             /* the child already logged the failure details */
2047             return;
2048         }
2049     }
2050
2051     max_daemons_limit = last_non_dead + 1;
2052
2053     if (idle_thread_count > max_spare_threads) {
2054         /* Kill off one child */
2055         ap_event_pod_signal(pod, TRUE);
2056         idle_spawn_rate = 1;
2057     }
2058     else if (idle_thread_count < min_spare_threads) {
2059         /* terminate the free list */
2060         if (free_length == 0) { /* scoreboard is full, can't fork */
2061
2062             if (active_thread_count >= ap_daemons_limit * threads_per_child) {
2063                 static int reported = 0;
2064                 if (!reported) {
2065                     /* only report this condition once */
2066                     ap_log_error(APLOG_MARK, APLOG_ERR, 0,
2067                                  ap_server_conf,
2068                                  "server reached MaxClients setting, consider"
2069                                  " raising the MaxClients setting");
2070                     reported = 1;
2071                 }
2072             }
2073             else {
2074                 ap_log_error(APLOG_MARK, APLOG_ERR, 0,
2075                              ap_server_conf,
2076                              "scoreboard is full, not at MaxClients");
2077             }
2078             idle_spawn_rate = 1;
2079         }
2080         else {
2081             if (free_length > idle_spawn_rate) {
2082                 free_length = idle_spawn_rate;
2083             }
2084             if (idle_spawn_rate >= 8) {
2085                 ap_log_error(APLOG_MARK, APLOG_INFO, 0,
2086                              ap_server_conf,
2087                              "server seems busy, (you may need "
2088                              "to increase StartServers, ThreadsPerChild "
2089                              "or Min/MaxSpareThreads), "
2090                              "spawning %d children, there are around %d idle "
2091                              "threads, and %d total children", free_length,
2092                              idle_thread_count, total_non_dead);
2093             }
2094             for (i = 0; i < free_length; ++i) {
2095                 make_child(ap_server_conf, free_slots[i]);
2096             }
2097             /* the next time around we want to spawn twice as many if this
2098              * wasn't good enough, but not if we've just done a graceful
2099              */
2100             if (hold_off_on_exponential_spawning) {
2101                 --hold_off_on_exponential_spawning;
2102             }
2103             else if (idle_spawn_rate < MAX_SPAWN_RATE) {
2104                 idle_spawn_rate *= 2;
2105             }
2106         }
2107     }
2108     else {
2109         idle_spawn_rate = 1;
2110     }
2111 }
2112
2113 static void server_main_loop(int remaining_children_to_start)
2114 {
2115     int child_slot;
2116     apr_exit_why_e exitwhy;
2117     int status, processed_status;
2118     apr_proc_t pid;
2119     int i;
2120
2121     while (!restart_pending && !shutdown_pending) {
2122         ap_wait_or_timeout(&exitwhy, &status, &pid, pconf);
2123
2124         if (pid.pid != -1) {
2125             processed_status = ap_process_child_status(&pid, exitwhy, status);
2126             if (processed_status == APEXIT_CHILDFATAL) {
2127                 shutdown_pending = 1;
2128                 child_fatal = 1;
2129                 return;
2130             }
2131             else if (processed_status == APEXIT_CHILDSICK) {
2132                 /* tell perform_idle_server_maintenance to check into this
2133                  * on the next timer pop
2134                  */
2135                 sick_child_detected = 1;
2136             }
2137             /* non-fatal death... note that it's gone in the scoreboard. */
2138             child_slot = ap_find_child_by_pid(&pid);
2139             if (child_slot >= 0) {
2140                 for (i = 0; i < threads_per_child; i++)
2141                     ap_update_child_status_from_indexes(child_slot, i,
2142                                                         SERVER_DEAD,
2143                                                         (request_rec *) NULL);
2144
2145                 ap_scoreboard_image->parent[child_slot].pid = 0;
2146                 ap_scoreboard_image->parent[child_slot].quiescing = 0;
2147                 if (processed_status == APEXIT_CHILDSICK) {
2148                     /* resource shortage, minimize the fork rate */
2149                     idle_spawn_rate = 1;
2150                 }
2151                 else if (remaining_children_to_start
2152                          && child_slot < ap_daemons_limit) {
2153                     /* we're still doing a 1-for-1 replacement of dead
2154                      * children with new children
2155                      */
2156                     make_child(ap_server_conf, child_slot);
2157                     --remaining_children_to_start;
2158                 }
2159             }
2160             else if (ap_unregister_extra_mpm_process(pid.pid) == 1) {
2161                 /* handled */
2162 #if APR_HAS_OTHER_CHILD
2163             }
2164             else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH,
2165                                                 status) == 0) {
2166                 /* handled */
2167 #endif
2168             }
2169             else if (is_graceful) {
2170                 /* Great, we've probably just lost a slot in the
2171                  * scoreboard.  Somehow we don't know about this child.
2172                  */
2173                 ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
2174                              ap_server_conf,
2175                              "long lost child came home! (pid %ld)",
2176                              (long) pid.pid);
2177             }
2178             /* Don't perform idle maintenance when a child dies,
2179              * only do it when there's a timeout.  Remember only a
2180              * finite number of children can die, and it's pretty
2181              * pathological for a lot to die suddenly.
2182              */
2183             continue;
2184         }
2185         else if (remaining_children_to_start) {
2186             /* we hit a 1 second timeout in which none of the previous
2187              * generation of children needed to be reaped... so assume
2188              * they're all done, and pick up the slack if any is left.
2189              */
2190             startup_children(remaining_children_to_start);
2191             remaining_children_to_start = 0;
2192             /* In any event we really shouldn't do the code below because
2193              * few of the servers we just started are in the IDLE state
2194              * yet, so we'd mistakenly create an extra server.
2195              */
2196             continue;
2197         }
2198
2199         perform_idle_server_maintenance();
2200     }
2201 }
2202
2203 static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
2204 {
2205     int remaining_children_to_start;
2206
2207     ap_log_pid(pconf, ap_pid_fname);
2208
2209     if (!is_graceful) {
2210         if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
2211             mpm_state = AP_MPMQ_STOPPING;
2212             return 1;
2213         }
2214         /* fix the generation number in the global score; we just got a new,
2215          * cleared scoreboard
2216          */
2217         ap_scoreboard_image->global->running_generation = my_generation;
2218     }
2219
2220     set_signals();
2221     /* Don't thrash... */
2222     if (max_spare_threads < min_spare_threads + threads_per_child)
2223         max_spare_threads = min_spare_threads + threads_per_child;
2224
2225     /* If we're doing a graceful_restart then we're going to see a lot
2226      * of children exiting immediately when we get into the main loop
2227      * below (because we just sent them AP_SIG_GRACEFUL).  This happens pretty
2228      * rapidly... and for each one that exits we may start a new one, until
2229      * there are at least min_spare_threads idle threads, counting across
2230      * all children.  But we may be permitted to start more children than
2231      * that, so we'll just keep track of how many we're
2232      * supposed to start up without the 1 second penalty between each fork.
2233      */
2234     remaining_children_to_start = ap_daemons_to_start;
2235     if (remaining_children_to_start > ap_daemons_limit) {
2236         remaining_children_to_start = ap_daemons_limit;
2237     }
2238     if (!is_graceful) {
2239         startup_children(remaining_children_to_start);
2240         remaining_children_to_start = 0;
2241     }
2242     else {
2243         /* give the system some time to recover before kicking into
2244          * exponential mode */
2245         hold_off_on_exponential_spawning = 10;
2246     }
2247
2248     ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2249                  "%s configured -- resuming normal operations",
2250                  ap_get_server_description());
2251     ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
2252                  "Server built: %s", ap_get_server_built());
2253
2254     restart_pending = shutdown_pending = 0;
2255     mpm_state = AP_MPMQ_RUNNING;
2256
2257     server_main_loop(remaining_children_to_start);
2258     mpm_state = AP_MPMQ_STOPPING;
2259
2260     if (shutdown_pending && !is_graceful) {
2261         /* Time to shut down:
2262          * Kill child processes, tell them to call child_exit, etc...
2263          */
2264         ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
2265         ap_reclaim_child_processes(1);  /* Start with SIGTERM */
2266
2267         if (!child_fatal) {
2268             /* cleanup pid file on normal shutdown */
2269             const char *pidfile = NULL;
2270             pidfile = ap_server_root_relative(pconf, ap_pid_fname);
2271             if (pidfile != NULL && unlink(pidfile) == 0)
2272                 ap_log_error(APLOG_MARK, APLOG_INFO, 0,
2273                              ap_server_conf,
2274                              "removed PID file %s (pid=%ld)",
2275                              pidfile, (long) getpid());
2276
2277             ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,
2278                          ap_server_conf, "caught SIGTERM, shutting down");
2279         }
2280         return 1;
2281     } else if (shutdown_pending) {
2282         /* Time to gracefully shut down:
2283          * Kill child processes, tell them to call child_exit, etc...
2284          */
2285         int active_children;
2286         int index;
2287         apr_time_t cutoff = 0;
2288
2289         /* Close our listeners, and then ask our children to do same */
2290         ap_close_listeners();
2291         ap_event_pod_killpg(pod, ap_daemons_limit, TRUE);
2292         ap_relieve_child_processes();
2293
2294         if (!child_fatal) {
2295             /* cleanup pid file on normal shutdown */
2296             const char *pidfile = NULL;
2297             pidfile = ap_server_root_relative (pconf, ap_pid_fname);
2298             if ( pidfile != NULL && unlink(pidfile) == 0)
2299                 ap_log_error(APLOG_MARK, APLOG_INFO, 0,
2300                              ap_server_conf,
2301                              "removed PID file %s (pid=%ld)",
2302                              pidfile, (long)getpid());
2303
2304             ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2305                          "caught " AP_SIG_GRACEFUL_STOP_STRING
2306                          ", shutting down gracefully");
2307         }
2308
2309         if (ap_graceful_shutdown_timeout) {
2310             cutoff = apr_time_now() +
2311                      apr_time_from_sec(ap_graceful_shutdown_timeout);
2312         }
2313
2314         /* Don't really exit until each child has finished */
2315         shutdown_pending = 0;
2316         do {
2317             /* Pause for a second */
2318             apr_sleep(apr_time_from_sec(1));
2319
2320             /* Relieve any children which have now exited */
2321             ap_relieve_child_processes();
2322
2323             active_children = 0;
2324             for (index = 0; index < ap_daemons_limit; ++index) {
2325                 if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == APR_SUCCESS) {
2326                     active_children = 1;
2327                     /* Having just one child is enough to stay around */
2328                     break;
2329                 }
2330             }
2331         } while (!shutdown_pending && active_children &&
2332                  (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
2333
2334         /* We might be here because we received SIGTERM, either
2335          * way, try and make sure that all of our processes are
2336          * really dead.
2337          */
2338         ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
2339         ap_reclaim_child_processes(1);
2340
2341         return 1;
2342     }
2343
2344     /* we've been told to restart */
2345     apr_signal(SIGHUP, SIG_IGN);
2346
2347     if (one_process) {
2348         /* not worth thinking about */
2349         return 1;
2350     }
2351
2352     /* advance to the next generation */
2353     /* XXX: we really need to make sure this new generation number isn't in
2354      * use by any of the children.
2355      */
2356     ++my_generation;
2357     ap_scoreboard_image->global->running_generation = my_generation;
2358
2359     if (is_graceful) {
2360         ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2361                      AP_SIG_GRACEFUL_STRING
2362                      " received.  Doing graceful restart");
2363         /* wake up the children...time to die.  But we'll have more soon */
2364         ap_event_pod_killpg(pod, ap_daemons_limit, TRUE);
2365
2366
2367         /* This is mostly for debugging... so that we know what is still
2368          * gracefully dealing with existing request.
2369          */
2370
2371     }
2372     else {
2373         /* Kill 'em all.  Since the child acts the same on the parents SIGTERM
2374          * and a SIGHUP, we may as well use the same signal, because some user
2375          * pthreads are stealing signals from us left and right.
2376          */
2377         ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
2378
2379         ap_reclaim_child_processes(1);  /* Start with SIGTERM */
2380         ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2381                      "SIGHUP received.  Attempting to restart");
2382     }
2383
2384     return 0;
2385 }
2386
2387 /* This really should be a post_config hook, but the error log is already
2388  * redirected by that point, so we need to do this in the open_logs phase.
2389  */
2390 static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
2391                            apr_pool_t * ptemp, server_rec * s)
2392 {
2393     int startup = 0;
2394     int level_flags = 0;
2395     apr_status_t rv;
2396
2397     pconf = p;
2398
2399     /* the reverse of pre_config, we want this only the first time around */
2400     if (retained->module_loads == 1) {
2401         startup = 1;
2402         level_flags |= APLOG_STARTUP;
2403     }
2404
2405     if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {
2406         ap_log_error(APLOG_MARK, APLOG_ALERT | level_flags, 0,
2407                      (startup ? NULL : s),
2408                      "no listening sockets available, shutting down");
2409         return DONE;
2410     }
2411
2412     if (!one_process) {
2413         if ((rv = ap_event_pod_open(pconf, &pod))) {
2414             ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
2415                          (startup ? NULL : s),
2416                          "could not open pipe-of-death");
2417             return DONE;
2418         }
2419     }
2420     return OK;
2421 }
2422
2423 static int event_pre_config(apr_pool_t * pconf, apr_pool_t * plog,
2424                             apr_pool_t * ptemp)
2425 {
2426     int no_detach, debug, foreground;
2427     apr_status_t rv;
2428     const char *userdata_key = "mpm_event_module";
2429
2430     mpm_state = AP_MPMQ_STARTING;
2431
2432     debug = ap_exists_config_define("DEBUG");
2433
2434     if (debug) {
2435         foreground = one_process = 1;
2436         no_detach = 0;
2437     }
2438     else {
2439         one_process = ap_exists_config_define("ONE_PROCESS");
2440         no_detach = ap_exists_config_define("NO_DETACH");
2441         foreground = ap_exists_config_define("FOREGROUND");
2442     }
2443
2444     /* sigh, want this only the second time around */
2445     retained = ap_retained_data_get(userdata_key);
2446     if (!retained) {
2447         retained = ap_retained_data_create(userdata_key, sizeof(*retained));
2448     }
2449     ++retained->module_loads;
2450     if (retained->module_loads == 2) {
2451         is_graceful = 0;
2452         rv = apr_pollset_create(&event_pollset, 1, plog,
2453                                 APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY);
2454         if (rv != APR_SUCCESS) {
2455             ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,
2456                          "Couldn't create a Thread Safe Pollset. "
2457                          "Is it supported on your platform?");
2458             return HTTP_INTERNAL_SERVER_ERROR;
2459         }
2460         apr_pollset_destroy(event_pollset);
2461
2462         if (!one_process && !foreground) {
2463             rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND
2464                                  : APR_PROC_DETACH_DAEMONIZE);
2465             if (rv != APR_SUCCESS) {
2466                 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,
2467                              "apr_proc_detach failed");
2468                 return HTTP_INTERNAL_SERVER_ERROR;
2469             }
2470         }
2471         parent_pid = ap_my_pid = getpid();
2472     }
2473
2474     ap_listen_pre_config();
2475     ap_daemons_to_start = DEFAULT_START_DAEMON;
2476     min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
2477     max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
2478     server_limit = DEFAULT_SERVER_LIMIT;
2479     thread_limit = DEFAULT_THREAD_LIMIT;
2480     ap_daemons_limit = server_limit;
2481     threads_per_child = DEFAULT_THREADS_PER_CHILD;
2482     max_clients = ap_daemons_limit * threads_per_child;
2483     ap_pid_fname = DEFAULT_PIDLOG;
2484     ap_lock_fname = DEFAULT_LOCKFILE;
2485     ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
2486     ap_extended_status = 0;
2487     ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED;
2488
2489     apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir));
2490
2491     return OK;
2492 }
2493
2494 static int event_check_config(apr_pool_t *p, apr_pool_t *plog,
2495                               apr_pool_t *ptemp, server_rec *s)
2496 {
2497     int startup = 0;
2498
2499     /* the reverse of pre_config, we want this only the first time around */
2500     if (retained->module_loads == 1) {
2501         startup = 1;
2502     }
2503
2504     if (server_limit > MAX_SERVER_LIMIT) {
2505         if (startup) {
2506             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2507                          "WARNING: ServerLimit of %d exceeds compile-time "
2508                          "limit of", server_limit);
2509             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2510                          " %d servers, decreasing to %d.",
2511                          MAX_SERVER_LIMIT, MAX_SERVER_LIMIT);
2512         } else {
2513             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2514                          "ServerLimit of %d exceeds compile-time limit "
2515                          "of %d, decreasing to match",
2516                          server_limit, MAX_SERVER_LIMIT);
2517         }
2518         server_limit = MAX_SERVER_LIMIT;
2519     }
2520     else if (server_limit < 1) {
2521         if (startup) {
2522             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2523                          "WARNING: ServerLimit of %d not allowed, "
2524                          "increasing to 1.", server_limit);
2525         } else {
2526             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2527                          "ServerLimit of %d not allowed, increasing to 1",
2528                          server_limit);
2529         }
2530         server_limit = 1;
2531     }
2532
2533     /* you cannot change ServerLimit across a restart; ignore
2534      * any such attempts
2535      */
2536     if (!retained->first_server_limit) {
2537         retained->first_server_limit = server_limit;
2538     }
2539     else if (server_limit != retained->first_server_limit) {
2540         /* don't need a startup console version here */
2541         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2542                      "changing ServerLimit to %d from original value of %d "
2543                      "not allowed during restart",
2544                      server_limit, retained->first_server_limit);
2545         server_limit = retained->first_server_limit;
2546     }
2547
2548     if (thread_limit > MAX_THREAD_LIMIT) {
2549         if (startup) {
2550             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2551                          "WARNING: ThreadLimit of %d exceeds compile-time "
2552                          "limit of", thread_limit);
2553             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2554                          " %d threads, decreasing to %d.",
2555                          MAX_THREAD_LIMIT, MAX_THREAD_LIMIT);
2556         } else {
2557             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2558                          "ThreadLimit of %d exceeds compile-time limit "
2559                          "of %d, decreasing to match",
2560                          thread_limit, MAX_THREAD_LIMIT);
2561         }
2562         thread_limit = MAX_THREAD_LIMIT;
2563     }
2564     else if (thread_limit < 1) {
2565         if (startup) {
2566             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2567                          "WARNING: ThreadLimit of %d not allowed, "
2568                          "increasing to 1.", thread_limit);
2569         } else {
2570             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2571                          "ThreadLimit of %d not allowed, increasing to 1",
2572                          thread_limit);
2573         }
2574         thread_limit = 1;
2575     }
2576
2577     /* you cannot change ThreadLimit across a restart; ignore
2578      * any such attempts
2579      */
2580     if (!retained->first_thread_limit) {
2581         retained->first_thread_limit = thread_limit;
2582     }
2583     else if (thread_limit != retained->first_thread_limit) {
2584         /* don't need a startup console version here */
2585         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2586                      "changing ThreadLimit to %d from original value of %d "
2587                      "not allowed during restart",
2588                      thread_limit, retained->first_thread_limit);
2589         thread_limit = retained->first_thread_limit;
2590     }
2591
2592     if (threads_per_child > thread_limit) {
2593         if (startup) {
2594             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2595                          "WARNING: ThreadsPerChild of %d exceeds ThreadLimit "
2596                          "of", threads_per_child);
2597             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2598                          " %d threads, decreasing to %d.",
2599                          thread_limit, thread_limit);
2600             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2601                          " To increase, please see the ThreadLimit "
2602                          "directive.");
2603         } else {
2604             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2605                          "ThreadsPerChild of %d exceeds ThreadLimit "
2606                          "of %d, decreasing to match",
2607                          threads_per_child, thread_limit);
2608         }
2609         threads_per_child = thread_limit;
2610     }
2611     else if (threads_per_child < 1) {
2612         if (startup) {
2613             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2614                          "WARNING: ThreadsPerChild of %d not allowed, "
2615                          "increasing to 1.", threads_per_child);
2616         } else {
2617             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2618                          "ThreadsPerChild of %d not allowed, increasing to 1",
2619                          threads_per_child);
2620         }
2621         threads_per_child = 1;
2622     }
2623
2624     if (max_clients < threads_per_child) {
2625         if (startup) {
2626             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2627                          "WARNING: MaxClients of %d is less than "
2628                          "ThreadsPerChild of", max_clients);
2629             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2630                          " %d, increasing to %d.  MaxClients must be at "
2631                          "least as large",
2632                          threads_per_child, threads_per_child);
2633             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2634                          " as the number of threads in a single server.");
2635         } else {
2636             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2637                          "MaxClients of %d is less than ThreadsPerChild "
2638                          "of %d, increasing to match",
2639                          max_clients, threads_per_child);
2640         }
2641         max_clients = threads_per_child;
2642     }
2643
2644     ap_daemons_limit = max_clients / threads_per_child;
2645
2646     if (max_clients % threads_per_child) {
2647         int tmp_max_clients = ap_daemons_limit * threads_per_child;
2648
2649         if (startup) {
2650             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2651                          "WARNING: MaxClients of %d is not an integer "
2652                          "multiple of", max_clients);
2653             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2654                          " ThreadsPerChild of %d, decreasing to nearest "
2655                          "multiple %d,", threads_per_child,
2656                          tmp_max_clients);
2657             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2658                          " for a maximum of %d servers.",
2659                          ap_daemons_limit);
2660         } else {
2661             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2662                          "MaxClients of %d is not an integer multiple of "
2663                          "ThreadsPerChild of %d, decreasing to nearest "
2664                          "multiple %d", max_clients, threads_per_child,
2665                          tmp_max_clients);
2666         }
2667         max_clients = tmp_max_clients;
2668     }
2669
2670     if (ap_daemons_limit > server_limit) {
2671         if (startup) {
2672             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2673                          "WARNING: MaxClients of %d would require %d "
2674                          "servers and ", max_clients, ap_daemons_limit);
2675             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2676                          " would exceed ServerLimit of %d, decreasing to %d.",
2677                          server_limit, server_limit * threads_per_child);
2678             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2679                          " To increase, please see the ServerLimit "
2680                          "directive.");
2681         } else {
2682             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2683                          "MaxClients of %d would require %d servers and "
2684                          "exceed ServerLimit of %d, decreasing to %d",
2685                          max_clients, ap_daemons_limit, server_limit,
2686                          server_limit * threads_per_child);
2687         }
2688         ap_daemons_limit = server_limit;
2689     }
2690
2691     /* ap_daemons_to_start > ap_daemons_limit checked in ap_mpm_run() */
2692     if (ap_daemons_to_start < 0) {
2693         if (startup) {
2694             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2695                          "WARNING: StartServers of %d not allowed, "
2696                          "increasing to 1.", ap_daemons_to_start);
2697         } else {
2698             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2699                          "StartServers of %d not allowed, increasing to 1",
2700                          ap_daemons_to_start);
2701         }
2702         ap_daemons_to_start = 1;
2703     }
2704
2705     if (min_spare_threads < 1) {
2706         if (startup) {
2707             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2708                          "WARNING: MinSpareThreads of %d not allowed, "
2709                          "increasing to 1", min_spare_threads);
2710             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2711                          " to avoid almost certain server failure.");
2712             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2713                          " Please read the documentation.");
2714         } else {
2715             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2716                          "MinSpareThreads of %d not allowed, increasing to 1",
2717                          min_spare_threads);
2718         }
2719         min_spare_threads = 1;
2720     }
2721
2722     /* max_spare_threads < min_spare_threads + threads_per_child
2723      * checked in ap_mpm_run()
2724      */
2725
2726     return OK;
2727 }
2728
2729 static void event_hooks(apr_pool_t * p)
2730 {
2731     /* Our open_logs hook function must run before the core's, or stderr
2732      * will be redirected to a file, and the messages won't print to the
2733      * console.
2734      */
2735     static const char *const aszSucc[] = { "core.c", NULL };
2736     one_process = 0;
2737
2738     ap_hook_open_logs(event_open_logs, NULL, aszSucc, APR_HOOK_REALLY_FIRST);
2739     /* we need to set the MPM state before other pre-config hooks use MPM query
2740      * to retrieve it, so register as REALLY_FIRST
2741      */
2742     ap_hook_pre_config(event_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
2743     ap_hook_check_config(event_check_config, NULL, NULL, APR_HOOK_MIDDLE);
2744     ap_hook_mpm(event_run, NULL, NULL, APR_HOOK_MIDDLE);
2745     ap_hook_mpm_query(event_query, NULL, NULL, APR_HOOK_MIDDLE);
2746     ap_hook_mpm_note_child_killed(event_note_child_killed, NULL, NULL, APR_HOOK_MIDDLE);
2747     ap_hook_mpm_register_timed_callback(event_register_timed_callback, NULL, NULL,
2748                                         APR_HOOK_MIDDLE);
2749     ap_hook_mpm_get_name(event_get_name, NULL, NULL, APR_HOOK_MIDDLE);
2750 }
2751
2752 static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy,
2753                                         const char *arg)
2754 {
2755     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2756     if (err != NULL) {
2757         return err;
2758     }
2759
2760     ap_daemons_to_start = atoi(arg);
2761     return NULL;
2762 }
2763
2764 static const char *set_min_spare_threads(cmd_parms * cmd, void *dummy,
2765                                          const char *arg)
2766 {
2767     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2768     if (err != NULL) {
2769         return err;
2770     }
2771
2772     min_spare_threads = atoi(arg);
2773     return NULL;
2774 }
2775
2776 static const char *set_max_spare_threads(cmd_parms * cmd, void *dummy,
2777                                          const char *arg)
2778 {
2779     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2780     if (err != NULL) {
2781         return err;
2782     }
2783
2784     max_spare_threads = atoi(arg);
2785     return NULL;
2786 }
2787
2788 static const char *set_max_clients(cmd_parms * cmd, void *dummy,
2789                                    const char *arg)
2790 {
2791     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2792     if (err != NULL) {
2793         return err;
2794     }
2795
2796     max_clients = atoi(arg);
2797     return NULL;
2798 }
2799
2800 static const char *set_threads_per_child(cmd_parms * cmd, void *dummy,
2801                                          const char *arg)
2802 {
2803     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2804     if (err != NULL) {
2805         return err;
2806     }
2807
2808     threads_per_child = atoi(arg);
2809     return NULL;
2810 }
2811 static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg)
2812 {
2813     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2814     if (err != NULL) {
2815         return err;
2816     }
2817
2818     server_limit = atoi(arg);
2819     return NULL;
2820 }
2821
2822 static const char *set_thread_limit(cmd_parms * cmd, void *dummy,
2823                                     const char *arg)
2824 {
2825     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2826     if (err != NULL) {
2827         return err;
2828     }
2829
2830     thread_limit = atoi(arg);
2831     return NULL;
2832 }
2833
2834 static const command_rec event_cmds[] = {
2835     LISTEN_COMMANDS,
2836     AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
2837                   "Number of child processes launched at server startup"),
2838     AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF,
2839                   "Maximum number of child processes for this run of Apache"),
2840     AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF,
2841                   "Minimum number of idle threads, to handle request spikes"),
2842     AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF,
2843                   "Maximum number of idle threads"),
2844     AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF,
2845                   "Maximum number of threads alive at the same time"),
2846     AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF,
2847                   "Number of threads each child creates"),
2848     AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF,
2849                   "Maximum number of worker threads per child process for this "
2850                   "run of Apache - Upper limit for ThreadsPerChild"),
2851     AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND,
2852     {NULL}
2853 };
2854
2855 module AP_MODULE_DECLARE_DATA mpm_event_module = {
2856     MPM20_MODULE_STUFF,
2857     NULL,                       /* hook to run before apache parses args */
2858     NULL,                       /* create per-directory config structure */
2859     NULL,                       /* merge per-directory config structures */
2860     NULL,                       /* create per-server config structure */
2861     NULL,                       /* merge per-server config structures */
2862     event_cmds,                 /* command apr_table_t */
2863     event_hooks                 /* register_hooks */
2864 };