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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * This MPM tries to fix the 'keep alive problem' in HTTP.
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.
28 * The MPM assumes the underlying apr_pollset implementation 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.
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.
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`).
40 * For NetBSD, use at least 2.0.
42 * For Linux, you should use a 2.6 kernel, and make sure your glibc has epoll
43 * support compiled in.
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"
56 #include "apr_queue.h"
57 #include "apr_atomic.h"
58 #define APR_WANT_STRFUNC
60 #include "apr_version.h"
65 #if APR_HAVE_SYS_SOCKET_H
66 #include <sys/socket.h>
68 #if APR_HAVE_SYS_WAIT_H
71 #ifdef HAVE_SYS_PROCESSOR_H
72 #include <sys/processor.h> /* for bindprocessor() */
76 #error The Event MPM requires APR threads, but they are unavailable.
79 #include "ap_config.h"
81 #include "http_main.h"
83 #include "http_config.h" /* for read_config */
84 #include "http_core.h" /* for get_remote_host */
85 #include "http_connection.h"
88 #include "mpm_common.h"
89 #include "ap_listen.h"
90 #include "scoreboard.h"
92 #include "mpm_default.h"
93 #include "http_vhost.h"
97 #include <limits.h> /* for INT_MAX */
103 #include "mod_serf.h"
107 /* Limit on the total --- clients will be locked out if more servers than
108 * this are needed. It is intended solely to keep the server from crashing
109 * when things get out of hand.
111 * We keep a hard maximum number of servers, for two reasons --- first off,
112 * in case something goes seriously wrong, we want to stop the fork bomb
113 * short of actually crashing the machine we're running on by filling some
114 * kernel table. Secondly, it keeps the size of the scoreboard file small
115 * enough that we can read the whole thing without worrying too much about
118 #ifndef DEFAULT_SERVER_LIMIT
119 #define DEFAULT_SERVER_LIMIT 16
122 /* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want
123 * some sort of compile-time limit to help catch typos.
125 #ifndef MAX_SERVER_LIMIT
126 #define MAX_SERVER_LIMIT 20000
129 /* Limit on the threads per process. Clients will be locked out if more than
132 * We keep this for one reason it keeps the size of the scoreboard file small
133 * enough that we can read the whole thing without worrying too much about
136 #ifndef DEFAULT_THREAD_LIMIT
137 #define DEFAULT_THREAD_LIMIT 64
140 /* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT. We want
141 * some sort of compile-time limit to help catch typos.
143 #ifndef MAX_THREAD_LIMIT
144 #define MAX_THREAD_LIMIT 100000
147 #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
149 #if !APR_VERSION_AT_LEAST(1,4,0)
150 #define apr_time_from_msec(x) (x * 1000)
153 #ifndef MAX_SECS_TO_LINGER
154 #define MAX_SECS_TO_LINGER 30
156 #define SECONDS_TO_LINGER 2
159 * Actual definitions of config globals
162 #ifndef DEFAULT_WORKER_FACTOR
163 #define DEFAULT_WORKER_FACTOR 2
165 #define WORKER_FACTOR_SCALE 16 /* scale factor to allow fractional values */
166 static unsigned int worker_factor = DEFAULT_WORKER_FACTOR * WORKER_FACTOR_SCALE;
168 static int threads_per_child = 0; /* Worker threads per child */
169 static int ap_daemons_to_start = 0;
170 static int min_spare_threads = 0;
171 static int max_spare_threads = 0;
172 static int ap_daemons_limit = 0;
173 static int max_workers = 0;
174 static int server_limit = 0;
175 static int thread_limit = 0;
176 static int dying = 0;
177 static int workers_may_exit = 0;
178 static int start_thread_may_exit = 0;
179 static int listener_may_exit = 0;
180 static int requests_this_child;
181 static int num_listensocks = 0;
182 static apr_uint32_t connection_count = 0;
183 static int resource_shortage = 0;
184 static fd_queue_t *worker_queue;
185 static fd_queue_info_t *worker_queue_info;
186 static int mpm_state = AP_MPMQ_STARTING;
189 TIMEOUT_WRITE_COMPLETION,
195 struct event_conn_state_t {
196 /** APR_RING of expiration timeouts */
197 APR_RING_ENTRY(event_conn_state_t) timeout_list;
198 /** the expiration time of the next keepalive timeout */
199 apr_time_t expiration_time;
200 /** connection record this struct refers to */
202 /** memory pool to allocate from */
204 /** bucket allocator */
205 apr_bucket_alloc_t *bucket_alloc;
206 /** poll file descriptor information */
208 /** public parts of the connection state */
212 typedef struct pollset_op_t {
213 timeout_type_e timeout_type;
214 event_conn_state_t *cs;
219 APR_RING_HEAD(timeout_head_t, event_conn_state_t);
220 struct timeout_queue {
221 struct timeout_head_t head;
226 * Several timeout queues that use different timeouts, so that we always can
227 * simply append to the end.
228 * write_completion_q uses TimeOut
229 * keepalive_q uses KeepAliveTimeOut
230 * linger_q uses MAX_SECS_TO_LINGER
231 * short_linger_q uses SECONDS_TO_LINGER
233 static struct timeout_queue write_completion_q, keepalive_q, linger_q,
235 static apr_pollfd_t *listener_pollfd;
238 * Macros for accessing struct timeout_queue.
239 * For TO_QUEUE_APPEND and TO_QUEUE_REMOVE, timeout_mutex must be held.
241 #define TO_QUEUE_APPEND(q, el) \
243 APR_RING_INSERT_TAIL(&(q).head, el, event_conn_state_t, timeout_list); \
247 #define TO_QUEUE_REMOVE(q, el) \
249 APR_RING_REMOVE(el, timeout_list); \
253 #define TO_QUEUE_INIT(q) \
255 APR_RING_INIT(&(q).head, event_conn_state_t, timeout_list); \
259 #define TO_QUEUE_ELEM_INIT(el) APR_RING_ELEM_INIT(el, timeout_list)
262 * The pollset for sockets that are in any of the timeout queues. Currently
263 * we use the timeout_mutex to make sure that connections are added/removed
264 * atomically to/from both event_pollset and a timeout queue. Otherwise
265 * some confusion can happen under high load if timeout queues and pollset
267 * XXX: It should be possible to make the lock unnecessary in many or even all
270 static apr_pollset_t *event_pollset;
274 apr_pollset_t *pollset;
278 static serf_context_t *g_serf;
281 /* The structure used to pass unique initialization info to each thread */
289 /* Structure used to pass information to the thread responsible for
290 * creating the rest of the threads.
294 apr_thread_t **threads;
295 apr_thread_t *listener;
297 apr_threadattr_t *threadattr;
313 } listener_poll_type;
315 /* data retained by event across load/unload of the module
316 * allocated on first call to pre-config hook; located on
317 * subsequent calls to pre-config hook
319 typedef struct event_retained_data {
320 int first_server_limit;
321 int first_thread_limit;
323 int sick_child_detected;
324 ap_generation_t my_generation;
325 int volatile is_graceful; /* set from signal handler */
326 int maxclients_reported;
328 * The max child slot ever assigned, preserved across restarts. Necessary
329 * to deal with MaxRequestWorkers changes across AP_SIG_GRACEFUL restarts.
330 * We use this value to optimize routines that have to scan the entire
333 int max_daemons_limit;
335 * idle_spawn_rate is the number of children that will be spawned on the
336 * next maintenance cycle if there aren't enough idle servers. It is
337 * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
338 * without the need to spawn.
341 #ifndef MAX_SPAWN_RATE
342 #define MAX_SPAWN_RATE (32)
344 int hold_off_on_exponential_spawning;
345 } event_retained_data;
346 static event_retained_data *retained;
348 #define ID_FROM_CHILD_THREAD(c, t) ((c * thread_limit) + t)
350 static ap_event_pod_t *pod;
352 /* The event MPM respects a couple of runtime flags that can aid
353 * in debugging. Setting the -DNO_DETACH flag will prevent the root process
354 * from detaching from its controlling terminal. Additionally, setting
355 * the -DONE_PROCESS flag (which implies -DNO_DETACH) will get you the
356 * child_main loop running in the process which originally started up.
357 * This gives you a pretty nice debugging environment. (You'll get a SIGHUP
358 * early in standalone_main; just continue through. This is the server
359 * trying to kill off any child processes which it might have lying
360 * around --- Apache doesn't keep track of their pids, it just sends
361 * SIGHUP to the process group, ignoring it in the root process.
362 * Continue through and you'll be fine.).
365 static int one_process = 0;
368 int raise_sigstop_flags;
371 static apr_pool_t *pconf; /* Pool for config stuff */
372 static apr_pool_t *pchild; /* Pool for httpd child stuff */
374 static pid_t ap_my_pid; /* Linux getpid() doesn't work except in main
375 thread. Use this instead */
376 static pid_t parent_pid;
377 static apr_os_thread_t *listener_os_thread;
379 /* The LISTENER_SIGNAL signal will be sent from the main thread to the
380 * listener thread to wake it up for graceful termination (what a child
381 * process from an old generation does when the admin does "apachectl
382 * graceful"). This signal will be blocked in all threads of a child
383 * process except for the listener thread.
385 #define LISTENER_SIGNAL SIGHUP
387 /* An array of socket descriptors in use by each thread used to
388 * perform a non-graceful (forced) shutdown of the server.
390 static apr_socket_t **worker_sockets;
391 static ap_equeue_t **worker_equeues;
393 static void disable_listensocks(int process_slot)
396 for (i = 0; i < num_listensocks; i++) {
397 apr_pollset_remove(event_pollset, &listener_pollfd[i]);
399 ap_scoreboard_image->parent[process_slot].not_accepting = 1;
402 static void enable_listensocks(int process_slot)
405 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
406 "Accepting new connections again: "
407 "%u active conns, %u idle workers",
408 apr_atomic_read32(&connection_count),
409 ap_queue_info_get_idlers(worker_queue_info));
410 for (i = 0; i < num_listensocks; i++)
411 apr_pollset_add(event_pollset, &listener_pollfd[i]);
413 * XXX: This is not yet optimal. If many workers suddenly become available,
414 * XXX: the parent may kill some processes off too soon.
416 ap_scoreboard_image->parent[process_slot].not_accepting = 0;
419 static void close_worker_sockets(void)
422 for (i = 0; i < threads_per_child; i++) {
423 if (worker_sockets[i]) {
424 apr_socket_close(worker_sockets[i]);
425 worker_sockets[i] = NULL;
430 static void wakeup_listener(void)
432 listener_may_exit = 1;
433 if (!listener_os_thread) {
434 /* XXX there is an obscure path that this doesn't handle perfectly:
435 * right after listener thread is created but before
436 * listener_os_thread is set, the first worker thread hits an
437 * error and starts graceful termination
442 /* unblock the listener if it's waiting for a worker */
443 ap_queue_info_term(worker_queue_info);
446 * we should just be able to "kill(ap_my_pid, LISTENER_SIGNAL)" on all
447 * platforms and wake up the listener thread since it is the only thread
448 * with SIGHUP unblocked, but that doesn't work on Linux
450 #ifdef HAVE_PTHREAD_KILL
451 pthread_kill(*listener_os_thread, LISTENER_SIGNAL);
453 kill(ap_my_pid, LISTENER_SIGNAL);
458 #define ST_GRACEFUL 1
459 #define ST_UNGRACEFUL 2
461 static int terminate_mode = ST_INIT;
463 static void signal_threads(int mode)
465 if (terminate_mode == mode) {
468 terminate_mode = mode;
469 mpm_state = AP_MPMQ_STOPPING;
471 /* in case we weren't called from the listener thread, wake up the
476 /* for ungraceful termination, let the workers exit now;
477 * for graceful termination, the listener thread will notify the
478 * workers to exit once it has stopped accepting new connections
480 if (mode == ST_UNGRACEFUL) {
481 workers_may_exit = 1;
482 ap_queue_interrupt_all(worker_queue);
483 close_worker_sockets(); /* forcefully kill all current connections */
487 static int event_query(int query_code, int *result, apr_status_t *rv)
490 switch (query_code) {
491 case AP_MPMQ_MAX_DAEMON_USED:
492 *result = retained->max_daemons_limit;
494 case AP_MPMQ_IS_THREADED:
495 *result = AP_MPMQ_STATIC;
497 case AP_MPMQ_IS_FORKED:
498 *result = AP_MPMQ_DYNAMIC;
500 case AP_MPMQ_IS_ASYNC:
503 case AP_MPMQ_HAS_SERF:
506 case AP_MPMQ_HARD_LIMIT_DAEMONS:
507 *result = server_limit;
509 case AP_MPMQ_HARD_LIMIT_THREADS:
510 *result = thread_limit;
512 case AP_MPMQ_MAX_THREADS:
513 *result = threads_per_child;
515 case AP_MPMQ_MIN_SPARE_DAEMONS:
518 case AP_MPMQ_MIN_SPARE_THREADS:
519 *result = min_spare_threads;
521 case AP_MPMQ_MAX_SPARE_DAEMONS:
524 case AP_MPMQ_MAX_SPARE_THREADS:
525 *result = max_spare_threads;
527 case AP_MPMQ_MAX_REQUESTS_DAEMON:
528 *result = ap_max_requests_per_child;
530 case AP_MPMQ_MAX_DAEMONS:
531 *result = ap_daemons_limit;
533 case AP_MPMQ_MPM_STATE:
536 case AP_MPMQ_GENERATION:
537 *result = retained->my_generation;
546 static void event_note_child_killed(int childnum, pid_t pid, ap_generation_t gen)
548 if (childnum != -1) { /* child had a scoreboard slot? */
549 ap_run_child_status(ap_server_conf,
550 ap_scoreboard_image->parent[childnum].pid,
551 ap_scoreboard_image->parent[childnum].generation,
552 childnum, MPM_CHILD_EXITED);
553 ap_scoreboard_image->parent[childnum].pid = 0;
556 ap_run_child_status(ap_server_conf, pid, gen, -1, MPM_CHILD_EXITED);
560 static void event_note_child_started(int slot, pid_t pid)
562 ap_scoreboard_image->parent[slot].pid = pid;
563 ap_run_child_status(ap_server_conf,
564 ap_scoreboard_image->parent[slot].pid,
565 retained->my_generation, slot, MPM_CHILD_STARTED);
568 static void event_note_child_lost_slot(int slot, pid_t newpid)
570 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
571 "pid %" APR_PID_T_FMT " taking over scoreboard slot from "
572 "%" APR_PID_T_FMT "%s",
574 ap_scoreboard_image->parent[slot].pid,
575 ap_scoreboard_image->parent[slot].quiescing ?
576 " (quiescing)" : "");
577 ap_run_child_status(ap_server_conf,
578 ap_scoreboard_image->parent[slot].pid,
579 ap_scoreboard_image->parent[slot].generation,
580 slot, MPM_CHILD_LOST_SLOT);
581 /* Don't forget about this exiting child process, or we
582 * won't be able to kill it if it doesn't exit by the
583 * time the server is shut down.
585 ap_register_extra_mpm_process(ap_scoreboard_image->parent[slot].pid,
586 ap_scoreboard_image->parent[slot].generation);
589 static const char *event_get_name(void)
594 /* a clean exit from a child with proper cleanup */
595 static void clean_child_exit(int code) __attribute__ ((noreturn));
596 static void clean_child_exit(int code)
598 mpm_state = AP_MPMQ_STOPPING;
600 apr_pool_destroy(pchild);
604 event_note_child_killed(/* slot */ 0, 0, 0);
610 static void just_die(int sig)
615 /*****************************************************************
616 * Connection structures and accounting...
619 static int child_fatal;
621 /* volatile because they're updated from a signal handler */
622 static int volatile shutdown_pending;
623 static int volatile restart_pending;
625 static apr_status_t decrement_connection_count(void *dummy) {
626 apr_atomic_dec32(&connection_count);
631 * ap_start_shutdown() and ap_start_restart(), below, are a first stab at
632 * functions to initiate shutdown or restart without relying on signals.
633 * Previously this was initiated in sig_term() and restart() signal handlers,
634 * but we want to be able to start a shutdown/restart from other sources --
635 * e.g. on Win32, from the service manager. Now the service manager can
636 * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that
637 * these functions can also be called by the child processes, since global
638 * variables are no longer used to pass on the required action to the parent.
640 * These should only be called from the parent process itself, since the
641 * parent process will use the shutdown_pending and restart_pending variables
642 * to determine whether to shutdown or restart. The child process should
643 * call signal_parent() directly to tell the parent to die -- this will
644 * cause neither of those variable to be set, which the parent will
645 * assume means something serious is wrong (which it will be, for the
646 * child to force an exit) and so do an exit anyway.
649 static void ap_start_shutdown(int graceful)
651 mpm_state = AP_MPMQ_STOPPING;
652 if (shutdown_pending == 1) {
653 /* Um, is this _probably_ not an error, if the user has
654 * tried to do a shutdown twice quickly, so we won't
655 * worry about reporting it.
659 shutdown_pending = 1;
660 retained->is_graceful = graceful;
663 /* do a graceful restart if graceful == 1 */
664 static void ap_start_restart(int graceful)
666 mpm_state = AP_MPMQ_STOPPING;
667 if (restart_pending == 1) {
668 /* Probably not an error - don't bother reporting it */
672 retained->is_graceful = graceful;
675 static void sig_term(int sig)
677 ap_start_shutdown(sig == AP_SIG_GRACEFUL_STOP);
680 static void restart(int sig)
682 ap_start_restart(sig == AP_SIG_GRACEFUL);
685 static void set_signals(void)
687 #ifndef NO_USE_SIGACTION
692 ap_fatal_signal_setup(ap_server_conf, pconf);
695 #ifndef NO_USE_SIGACTION
696 sigemptyset(&sa.sa_mask);
699 sa.sa_handler = sig_term;
700 if (sigaction(SIGTERM, &sa, NULL) < 0)
701 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
702 "sigaction(SIGTERM)");
703 #ifdef AP_SIG_GRACEFUL_STOP
704 if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0)
705 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
706 "sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")");
709 if (sigaction(SIGINT, &sa, NULL) < 0)
710 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
711 "sigaction(SIGINT)");
714 sa.sa_handler = SIG_DFL;
715 if (sigaction(SIGXCPU, &sa, NULL) < 0)
716 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
717 "sigaction(SIGXCPU)");
720 /* For systems following the LFS standard, ignoring SIGXFSZ allows
721 * a write() beyond the 2GB limit to fail gracefully with E2BIG
722 * rather than terminate the process. */
723 sa.sa_handler = SIG_IGN;
724 if (sigaction(SIGXFSZ, &sa, NULL) < 0)
725 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
726 "sigaction(SIGXFSZ)");
729 sa.sa_handler = SIG_IGN;
730 if (sigaction(SIGPIPE, &sa, NULL) < 0)
731 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
732 "sigaction(SIGPIPE)");
735 /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy
737 sigaddset(&sa.sa_mask, SIGHUP);
738 sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL);
739 sa.sa_handler = restart;
740 if (sigaction(SIGHUP, &sa, NULL) < 0)
741 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
742 "sigaction(SIGHUP)");
743 if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0)
744 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
745 "sigaction(" AP_SIG_GRACEFUL_STRING ")");
749 apr_signal(SIGXCPU, SIG_DFL);
752 apr_signal(SIGXFSZ, SIG_IGN);
756 apr_signal(SIGTERM, sig_term);
758 apr_signal(SIGHUP, restart);
760 #ifdef AP_SIG_GRACEFUL
761 apr_signal(AP_SIG_GRACEFUL, restart);
762 #endif /* AP_SIG_GRACEFUL */
763 #ifdef AP_SIG_GRACEFUL_STOP
764 apr_signal(AP_SIG_GRACEFUL_STOP, sig_term);
765 #endif /* AP_SIG_GRACEFUL_STOP */
767 apr_signal(SIGPIPE, SIG_IGN);
773 static void process_pollop(pollset_op_t *op)
776 event_conn_state_t *cs = op->cs;
778 switch (op->timeout_type) {
779 case TIMEOUT_WRITE_COMPLETION:
780 TO_QUEUE_APPEND(write_completion_q, cs);
782 case TIMEOUT_KEEPALIVE:
783 TO_QUEUE_APPEND(keepalive_q, cs);
786 TO_QUEUE_APPEND(linger_q, cs);
788 case TIMEOUT_SHORT_LINGER:
789 TO_QUEUE_APPEND(short_linger_q, cs);
793 rv = apr_pollset_add(event_pollset, &op->cs->pfd);
795 if (rv != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rv)) {
796 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
797 "%s: apr_pollset_add failure", op->tag);
802 * close our side of the connection
803 * Pre-condition: cs is not in any timeout queue and not in the pollset,
804 * timeout_mutex is not locked
805 * return: 0 if connection is fully closed,
806 * 1 if connection is lingering
807 * may be called by listener or by worker thread.
808 * the eq may be null if called from the listener thread,
809 * and the pollset operations are done directly by this function.
811 static int start_lingering_close(event_conn_state_t *cs, ap_equeue_t *eq)
815 cs->c->sbh = NULL; /* prevent scoreboard updates from the listener
816 * worker will loop around soon and set SERVER_READY
819 if (ap_start_lingering_close(cs->c)) {
820 apr_pool_clear(cs->p);
821 ap_push_pool(worker_queue_info, cs->p);
825 apr_socket_t *csd = ap_get_conn_socket(cs->c);
830 v = ap_equeue_writer_value(eq);
836 rv = apr_socket_timeout_set(csd, 0);
837 AP_DEBUG_ASSERT(rv == APR_SUCCESS);
839 * If some module requested a shortened waiting period, only wait for
840 * 2s (SECONDS_TO_LINGER). This is useful for mitigating certain
843 if (apr_table_get(cs->c->notes, "short-lingering-close")) {
844 cs->expiration_time =
845 apr_time_now() + apr_time_from_sec(SECONDS_TO_LINGER);
846 v->timeout_type = TIMEOUT_SHORT_LINGER;
847 v->tag = "start_lingering_close(short)";
848 cs->pub.state = CONN_STATE_LINGER_SHORT;
851 cs->expiration_time =
852 apr_time_now() + apr_time_from_sec(MAX_SECS_TO_LINGER);
853 v->timeout_type = TIMEOUT_LINGER;
854 v->tag = "start_lingering_close(normal)";
855 cs->pub.state = CONN_STATE_LINGER_NORMAL;
858 cs->pfd.reqevents = APR_POLLIN | APR_POLLHUP | APR_POLLERR;
861 ap_equeue_writer_onward(eq);
862 apr_pollset_wakeup(event_pollset);
872 * forcibly close a lingering connection after the lingering period has
874 * Pre-condition: cs is not in any timeout queue and not in the pollset
875 * return: irrelevant (need same prototype as start_lingering_close)
877 static int stop_lingering_close(event_conn_state_t *cs, ap_equeue_t *eq)
880 apr_socket_t *csd = ap_get_conn_socket(cs->c);
881 ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf,
882 "socket reached timeout in lingering-close state");
883 rv = apr_socket_close(csd);
884 if (rv != APR_SUCCESS) {
885 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, "error closing socket");
888 apr_pool_clear(cs->p);
889 ap_push_pool(worker_queue_info, cs->p);
894 * process one connection in the worker
895 * return: 1 if the connection has been completed,
896 * 0 if it is still open and waiting for some event
898 static int process_socket(apr_thread_t *thd, apr_pool_t * p, apr_socket_t * sock,
899 event_conn_state_t * cs,
905 long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num);
909 ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num);
911 if (cs == NULL) { /* This is a new connection */
912 listener_poll_type *pt = apr_pcalloc(p, sizeof(*pt));
913 cs = apr_pcalloc(p, sizeof(event_conn_state_t));
914 cs->bucket_alloc = apr_bucket_alloc_create(p);
915 c = ap_run_create_connection(p, ap_server_conf, sock,
916 conn_id, sbh, cs->bucket_alloc);
918 apr_bucket_alloc_destroy(cs->bucket_alloc);
920 ap_push_pool(worker_queue_info, p);
923 apr_atomic_inc32(&connection_count);
924 apr_pool_cleanup_register(c->pool, NULL, decrement_connection_count, apr_pool_cleanup_null);
925 c->current_thread = thd;
929 cs->pfd.desc_type = APR_POLL_SOCKET;
930 cs->pfd.reqevents = APR_POLLIN;
931 cs->pfd.desc.s = sock;
934 cs->pfd.client_data = pt;
936 ap_update_vhost_given_ip(c);
938 rc = ap_run_pre_connection(c, sock);
939 if (rc != OK && rc != DONE) {
940 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
941 "process_socket: connection aborted");
946 * XXX If the platform does not have a usable way of bundling
947 * accept() with a socket readability check, like Win32,
948 * and there are measurable delays before the
949 * socket is readable due to the first data packet arriving,
950 * it might be better to create the cs on the listener thread
951 * with the state set to CONN_STATE_CHECK_REQUEST_LINE_READABLE
953 * FreeBSD users will want to enable the HTTP accept filter
954 * module in their kernel for the highest performance
955 * When the accept filter is active, sockets are kept in the
956 * kernel until a HTTP request is received.
958 cs->pub.state = CONN_STATE_READ_REQUEST_LINE;
964 c->current_thread = thd;
967 if (c->clogging_input_filters && !c->aborted) {
968 /* Since we have an input filter which 'cloggs' the input stream,
969 * like mod_ssl, lets just do the normal read from input filters,
970 * like the Worker MPM does.
972 ap_run_process_connection(c);
973 if (cs->pub.state != CONN_STATE_SUSPENDED) {
974 cs->pub.state = CONN_STATE_LINGER;
979 if (cs->pub.state == CONN_STATE_READ_REQUEST_LINE) {
981 ap_run_process_connection(c);
983 /* state will be updated upon return
984 * fall thru to either wait for readability/timeout or
989 cs->pub.state = CONN_STATE_LINGER;
993 if (cs->pub.state == CONN_STATE_WRITE_COMPLETION) {
994 ap_filter_t *output_filter = c->output_filters;
996 ap_update_child_status_from_conn(sbh, SERVER_BUSY_WRITE, c);
997 while (output_filter->next != NULL) {
998 output_filter = output_filter->next;
1000 rv = output_filter->frec->filter_func.out_func(output_filter, NULL);
1001 if (rv != APR_SUCCESS) {
1002 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c,
1003 "network write failure in core output filter");
1004 cs->pub.state = CONN_STATE_LINGER;
1006 else if (c->data_in_output_filters) {
1007 /* Still in WRITE_COMPLETION_STATE:
1008 * Set a write timeout for this connection, and let the
1009 * event thread poll for writeability.
1011 pollset_op_t *v = ap_equeue_writer_value(eq);
1013 cs->expiration_time = ap_server_conf->timeout + apr_time_now();
1014 cs->pfd.reqevents = APR_POLLOUT | APR_POLLHUP | APR_POLLERR;
1017 v->timeout_type = TIMEOUT_WRITE_COMPLETION;
1018 v->tag = "process_socket(write_completion)";
1020 ap_equeue_writer_onward(eq);
1021 apr_pollset_wakeup(event_pollset);
1024 else if (c->keepalive != AP_CONN_KEEPALIVE || c->aborted ||
1025 listener_may_exit) {
1026 cs->pub.state = CONN_STATE_LINGER;
1028 else if (c->data_in_input_filters) {
1029 cs->pub.state = CONN_STATE_READ_REQUEST_LINE;
1033 cs->pub.state = CONN_STATE_CHECK_REQUEST_LINE_READABLE;
1037 if (cs->pub.state == CONN_STATE_LINGER) {
1038 if (!start_lingering_close(cs, eq)) {
1042 else if (cs->pub.state == CONN_STATE_CHECK_REQUEST_LINE_READABLE) {
1045 /* It greatly simplifies the logic to use a single timeout value here
1046 * because the new element can just be added to the end of the list and
1047 * it will stay sorted in expiration time sequence. If brand new
1048 * sockets are sent to the event thread for a readability check, this
1049 * will be a slight behavior change - they use the non-keepalive
1050 * timeout today. With a normal client, the socket will be readable in
1051 * a few milliseconds anyway.
1053 cs->expiration_time = ap_server_conf->keep_alive_timeout +
1056 /* Add work to pollset. */
1057 v = ap_equeue_writer_value(eq);
1058 v->timeout_type = TIMEOUT_KEEPALIVE;
1060 cs->pfd.reqevents = APR_POLLIN;
1061 v->tag = "process_socket(keepalive)";
1062 ap_equeue_writer_onward(eq);
1063 apr_pollset_wakeup(event_pollset);
1068 /* requests_this_child has gone to zero or below. See if the admin coded
1069 "MaxConnectionsPerChild 0", and keep going in that case. Doing it this way
1070 simplifies the hot path in worker_thread */
1071 static void check_infinite_requests(void)
1073 if (ap_max_requests_per_child) {
1074 signal_threads(ST_GRACEFUL);
1077 requests_this_child = INT_MAX; /* keep going */
1081 static void close_listeners(int process_slot, int *closed) {
1084 disable_listensocks(process_slot);
1085 ap_close_listeners();
1088 ap_scoreboard_image->parent[process_slot].quiescing = 1;
1089 for (i = 0; i < threads_per_child; ++i) {
1090 ap_update_child_status_from_indexes(process_slot, i,
1091 SERVER_GRACEFUL, NULL);
1093 /* wake up the main thread */
1094 kill(ap_my_pid, SIGTERM);
1098 static void unblock_signal(int sig)
1102 sigemptyset(&sig_mask);
1103 sigaddset(&sig_mask, sig);
1104 #if defined(SIGPROCMASK_SETS_THREAD_MASK)
1105 sigprocmask(SIG_UNBLOCK, &sig_mask, NULL);
1107 pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL);
1111 static void dummy_signal_handler(int sig)
1113 /* XXX If specifying SIG_IGN is guaranteed to unblock a syscall,
1114 * then we don't need this goofy function.
1120 static apr_status_t s_socket_add(void *user_baton,
1124 s_baton_t *s = (s_baton_t*)user_baton;
1125 /* XXXXX: recycle listener_poll_types */
1126 listener_poll_type *pt = ap_malloc(sizeof(*pt));
1128 pt->baton = serf_baton;
1129 pfd->client_data = pt;
1130 return apr_pollset_add(s->pollset, pfd);
1133 static apr_status_t s_socket_remove(void *user_baton,
1137 s_baton_t *s = (s_baton_t*)user_baton;
1138 listener_poll_type *pt = pfd->client_data;
1140 return apr_pollset_remove(s->pollset, pfd);
1144 static apr_status_t init_pollset(apr_pool_t *p)
1147 s_baton_t *baton = NULL;
1150 listener_poll_type *pt;
1153 TO_QUEUE_INIT(write_completion_q);
1154 TO_QUEUE_INIT(keepalive_q);
1155 TO_QUEUE_INIT(linger_q);
1156 TO_QUEUE_INIT(short_linger_q);
1158 listener_pollfd = apr_palloc(p, sizeof(apr_pollfd_t) * num_listensocks);
1159 for (lr = ap_listeners; lr != NULL; lr = lr->next, i++) {
1161 AP_DEBUG_ASSERT(i < num_listensocks);
1162 pfd = &listener_pollfd[i];
1163 pt = apr_pcalloc(p, sizeof(*pt));
1164 pfd->desc_type = APR_POLL_SOCKET;
1165 pfd->desc.s = lr->sd;
1166 pfd->reqevents = APR_POLLIN;
1168 pt->type = PT_ACCEPT;
1171 pfd->client_data = pt;
1173 apr_socket_opt_set(pfd->desc.s, APR_SO_NONBLOCK, 1);
1174 apr_pollset_add(event_pollset, pfd);
1176 lr->accept_func = ap_unixd_accept;
1180 baton = apr_pcalloc(p, sizeof(*baton));
1181 baton->pollset = event_pollset;
1182 /* TODO: subpools, threads, reuse, etc. -- currently use malloc() inside :( */
1185 g_serf = serf_context_create_ex(baton,
1187 s_socket_remove, p);
1189 ap_register_provider(p, "mpm_serf",
1190 "instance", "0", g_serf);
1197 static apr_status_t push_timer2worker(timer_event_t* te)
1199 return ap_queue_push_timer(worker_queue, te);
1203 * Pre-condition: pfd->cs is neither in pollset nor timeout queue
1204 * this function may only be called by the listener
1206 static apr_status_t push2worker(const apr_pollfd_t * pfd,
1207 apr_pollset_t * pollset)
1209 listener_poll_type *pt = (listener_poll_type *) pfd->client_data;
1210 event_conn_state_t *cs = (event_conn_state_t *) pt->baton;
1213 rc = ap_queue_push(worker_queue, cs->pfd.desc.s, cs, cs->p);
1214 if (rc != APR_SUCCESS) {
1215 /* trash the connection; we couldn't queue the connected
1216 * socket to a worker
1218 apr_bucket_alloc_destroy(cs->bucket_alloc);
1219 apr_socket_close(cs->pfd.desc.s);
1220 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1221 ap_server_conf, "push2worker: ap_queue_push failed");
1222 apr_pool_clear(cs->p);
1223 ap_push_pool(worker_queue_info, cs->p);
1230 * If *have_idle_worker_p == 0, reserve a worker thread, and set
1231 * *have_idle_worker_p = 1.
1232 * If *have_idle_worker_p is already 1, will do nothing.
1233 * If blocking == 1, block if all workers are currently busy.
1234 * If no worker was available immediately, will set *all_busy to 1.
1235 * XXX: If there are no workers, we should not block immediately but
1236 * XXX: close all keep-alive connections first.
1238 static void get_worker(int *have_idle_worker_p, int blocking, int *all_busy)
1242 if (*have_idle_worker_p) {
1243 /* already reserved a worker thread - must have hit a
1244 * transient error on a previous pass
1250 rc = ap_queue_info_wait_for_idler(worker_queue_info, all_busy);
1252 rc = ap_queue_info_try_get_idler(worker_queue_info);
1254 if (rc == APR_SUCCESS) {
1255 *have_idle_worker_p = 1;
1257 else if (!blocking && rc == APR_EAGAIN) {
1260 else if (!APR_STATUS_IS_EOF(rc)) {
1261 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
1262 "ap_queue_info_wait_for_idler failed. "
1263 "Attempting to shutdown process gracefully");
1264 signal_threads(ST_GRACEFUL);
1268 /* XXXXXX: Convert to skiplist or other better data structure
1269 * (yes, this is VERY VERY VERY VERY BAD)
1272 /* Structures to reuse */
1273 static APR_RING_HEAD(timer_free_ring_t, timer_event_t) timer_free_ring;
1275 static APR_RING_HEAD(timer_ring_t, timer_event_t) timer_ring;
1277 static apr_thread_mutex_t *g_timer_ring_mtx;
1279 static apr_status_t event_register_timed_callback(apr_time_t t,
1280 ap_mpm_callback_fn_t *cbfn,
1286 /* oh yeah, and make locking smarter/fine grained. */
1287 apr_thread_mutex_lock(g_timer_ring_mtx);
1289 if (!APR_RING_EMPTY(&timer_free_ring, timer_event_t, link)) {
1290 te = APR_RING_FIRST(&timer_free_ring);
1291 APR_RING_REMOVE(te, link);
1294 /* XXXXX: lol, pool allocation without a context from any thread.Yeah. Right. MPMs Suck. */
1295 te = ap_malloc(sizeof(timer_event_t));
1296 APR_RING_ELEM_INIT(te, link);
1301 /* XXXXX: optimize */
1302 te->when = t + apr_time_now();
1304 /* Okay, insert sorted by when.. */
1305 for (ep = APR_RING_FIRST(&timer_ring);
1306 ep != APR_RING_SENTINEL(&timer_ring,
1307 timer_event_t, link);
1308 ep = APR_RING_NEXT(ep, link))
1310 if (ep->when > te->when) {
1312 APR_RING_INSERT_BEFORE(ep, te, link);
1318 APR_RING_INSERT_TAIL(&timer_ring, te, timer_event_t, link);
1321 apr_thread_mutex_unlock(g_timer_ring_mtx);
1327 * Close socket and clean up if remote closed its end while we were in
1329 * Only to be called in the listener thread;
1330 * Pre-condition: cs is in one of the linger queues and in the pollset
1332 static void process_lingering_close(event_conn_state_t *cs, const apr_pollfd_t *pfd)
1334 apr_socket_t *csd = ap_get_conn_socket(cs->c);
1335 char dummybuf[2048];
1338 struct timeout_queue *q;
1339 q = (cs->pub.state == CONN_STATE_LINGER_SHORT) ? &short_linger_q : &linger_q;
1341 /* socket is already in non-blocking state */
1343 nbytes = sizeof(dummybuf);
1344 rv = apr_socket_recv(csd, dummybuf, &nbytes);
1345 } while (rv == APR_SUCCESS);
1347 if (!APR_STATUS_IS_EOF(rv)) {
1351 rv = apr_pollset_remove(event_pollset, pfd);
1352 AP_DEBUG_ASSERT(rv == APR_SUCCESS);
1354 rv = apr_socket_close(csd);
1355 AP_DEBUG_ASSERT(rv == APR_SUCCESS);
1357 TO_QUEUE_REMOVE(*q, cs);
1358 TO_QUEUE_ELEM_INIT(cs);
1360 apr_pool_clear(cs->p);
1361 ap_push_pool(worker_queue_info, cs->p);
1364 /* call 'func' for all elements of 'q' with timeout less than 'timeout_time'.
1365 * Pre-condition: timeout_mutex must already be locked
1366 * Post-condition: timeout_mutex will be locked again
1368 static void process_timeout_queue(struct timeout_queue *q,
1369 apr_time_t timeout_time,
1370 int (*func)(event_conn_state_t *, ap_equeue_t *eq))
1373 event_conn_state_t *first, *cs, *last;
1378 AP_DEBUG_ASSERT(!APR_RING_EMPTY(&q->head, event_conn_state_t, timeout_list));
1380 cs = first = APR_RING_FIRST(&q->head);
1381 while (cs != APR_RING_SENTINEL(&q->head, event_conn_state_t, timeout_list)
1382 && cs->expiration_time < timeout_time) {
1384 rv = apr_pollset_remove(event_pollset, &cs->pfd);
1385 if (rv != APR_SUCCESS && !APR_STATUS_IS_NOTFOUND(rv)) {
1386 ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, cs->c,
1387 "apr_pollset_remove failed");
1389 cs = APR_RING_NEXT(cs, timeout_list);
1395 APR_RING_UNSPLICE(first, last, timeout_list);
1396 AP_DEBUG_ASSERT(q->count >= count);
1399 cs = APR_RING_NEXT(first, timeout_list);
1400 TO_QUEUE_ELEM_INIT(first);
1407 static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy)
1412 proc_info *ti = dummy;
1413 int process_slot = ti->pid;
1414 apr_pool_t *tpool = apr_thread_pool_get(thd);
1416 apr_pool_t *ptrans; /* Pool for per-transaction stuff */
1418 int have_idle_worker = 0;
1419 event_conn_state_t *cs;
1420 const apr_pollfd_t *out_pfd;
1421 apr_int32_t num = 0;
1422 apr_interval_time_t timeout_interval;
1423 apr_time_t timeout_time = 0, now, last_log;
1424 listener_poll_type *pt;
1425 int closed = 0, listeners_disabled = 0;
1427 last_log = apr_time_now();
1430 /* the following times out events that are really close in the future
1431 * to prevent extra poll calls
1433 * current value is .1 second
1435 #define TIMEOUT_FUDGE_FACTOR 100000
1436 #define EVENT_FUDGE_FACTOR 10000
1438 rc = init_pollset(tpool);
1439 if (rc != APR_SUCCESS) {
1440 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
1441 "failed to initialize pollset, "
1442 "attempting to shutdown process gracefully");
1443 signal_threads(ST_GRACEFUL);
1447 /* Unblock the signal used to wake this thread up, and set a handler for
1450 unblock_signal(LISTENER_SIGNAL);
1451 apr_signal(LISTENER_SIGNAL, dummy_signal_handler);
1454 int workers_were_busy = 0;
1455 if (listener_may_exit) {
1456 close_listeners(process_slot, &closed);
1457 if (terminate_mode == ST_UNGRACEFUL
1458 || apr_atomic_read32(&connection_count) == 0)
1462 if (requests_this_child <= 0) {
1463 check_infinite_requests();
1466 now = apr_time_now();
1467 if (APLOGtrace6(ap_server_conf)) {
1468 /* trace log status every second */
1469 if (now - last_log > apr_time_from_msec(1000)) {
1471 ap_log_error(APLOG_MARK, APLOG_TRACE6, 0, ap_server_conf,
1472 "connections: %d (write-completion: %d "
1473 "keep-alive: %d lingering: %d)",
1474 connection_count, write_completion_q.count,
1476 linger_q.count + short_linger_q.count);
1480 apr_thread_mutex_lock(g_timer_ring_mtx);
1481 if (!APR_RING_EMPTY(&timer_ring, timer_event_t, link)) {
1482 te = APR_RING_FIRST(&timer_ring);
1483 if (te->when > now) {
1484 timeout_interval = te->when - now;
1487 timeout_interval = 1;
1491 timeout_interval = apr_time_from_msec(100);
1493 apr_thread_mutex_unlock(g_timer_ring_mtx);
1496 rc = serf_context_prerun(g_serf);
1497 if (rc != APR_SUCCESS) {
1498 /* TOOD: what should do here? ugh. */
1501 rc = apr_pollset_poll(event_pollset, timeout_interval, &num, &out_pfd);
1502 if (rc != APR_SUCCESS
1503 && !APR_STATUS_IS_EINTR(rc)
1504 && !APR_STATUS_IS_TIMEUP(rc)) {
1505 ap_log_error(APLOG_MARK, APLOG_CRIT, rc, ap_server_conf,
1506 "apr_pollset_poll failed. Attempting to "
1507 "shutdown process gracefully");
1508 signal_threads(ST_GRACEFUL);
1511 if (listener_may_exit) {
1512 close_listeners(process_slot, &closed);
1513 if (terminate_mode == ST_UNGRACEFUL
1514 || apr_atomic_read32(&connection_count) == 0)
1518 now = apr_time_now();
1519 apr_thread_mutex_lock(g_timer_ring_mtx);
1520 for (ep = APR_RING_FIRST(&timer_ring);
1521 ep != APR_RING_SENTINEL(&timer_ring,
1522 timer_event_t, link);
1523 ep = APR_RING_FIRST(&timer_ring))
1525 if (ep->when < now + EVENT_FUDGE_FACTOR) {
1526 APR_RING_REMOVE(ep, link);
1527 push_timer2worker(ep);
1533 apr_thread_mutex_unlock(g_timer_ring_mtx);
1536 pt = (listener_poll_type *) out_pfd->client_data;
1537 if (pt->type == PT_CSD) {
1538 /* one of the sockets is readable */
1539 struct timeout_queue *remove_from_q = &write_completion_q;
1541 cs = (event_conn_state_t *)pt->baton;
1542 switch (cs->pub.state) {
1543 case CONN_STATE_CHECK_REQUEST_LINE_READABLE:
1544 cs->pub.state = CONN_STATE_READ_REQUEST_LINE;
1545 remove_from_q = &keepalive_q;
1546 /* don't wait for a worker for a keepalive request */
1549 case CONN_STATE_WRITE_COMPLETION:
1550 get_worker(&have_idle_worker, blocking,
1551 &workers_were_busy);
1552 TO_QUEUE_REMOVE(*remove_from_q, cs);
1553 rc = apr_pollset_remove(event_pollset, &cs->pfd);
1556 * Some of the pollset backends, like KQueue or Epoll
1557 * automagically remove the FD if the socket is closed,
1558 * therefore, we can accept _SUCCESS or _NOTFOUND,
1559 * and we still want to keep going
1561 if (rc != APR_SUCCESS && !APR_STATUS_IS_NOTFOUND(rc)) {
1562 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
1563 "pollset remove failed");
1564 start_lingering_close(cs, NULL);
1568 TO_QUEUE_ELEM_INIT(cs);
1569 /* If we didn't get a worker immediately for a keep-alive
1570 * request, we close the connection, so that the client can
1571 * re-connect to a different process.
1573 if (!have_idle_worker) {
1574 start_lingering_close(cs, NULL);
1577 rc = push2worker(out_pfd, event_pollset);
1578 if (rc != APR_SUCCESS) {
1579 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1580 ap_server_conf, "push2worker failed");
1583 have_idle_worker = 0;
1586 case CONN_STATE_LINGER_NORMAL:
1587 case CONN_STATE_LINGER_SHORT:
1588 process_lingering_close(cs, out_pfd);
1591 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1593 "event_loop: unexpected state %d",
1598 else if (pt->type == PT_ACCEPT) {
1599 int skip_accept = 0;
1600 int connection_count_local = connection_count;
1602 /* A Listener Socket is ready for an accept() */
1603 if (workers_were_busy) {
1605 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1606 "All workers busy, not accepting new conns"
1609 else if (listeners_disabled) {
1610 listeners_disabled = 0;
1611 enable_listensocks(process_slot);
1613 else if (connection_count_local > threads_per_child
1614 + ap_queue_info_get_idlers(worker_queue_info) *
1615 worker_factor / WORKER_FACTOR_SCALE)
1618 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1619 "Too many open connections (%u), "
1620 "not accepting new conns in this process",
1621 connection_count_local);
1622 ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
1624 ap_queue_info_get_idlers(worker_queue_info));
1627 if (skip_accept == 0) {
1628 lr = (ap_listen_rec *) pt->baton;
1629 ap_pop_pool(&ptrans, worker_queue_info);
1631 if (ptrans == NULL) {
1632 /* create a new transaction pool for each accepted socket */
1633 apr_allocator_t *allocator;
1635 apr_allocator_create(&allocator);
1636 apr_allocator_max_free_set(allocator,
1638 apr_pool_create_ex(&ptrans, pconf, NULL, allocator);
1639 apr_allocator_owner_set(allocator, ptrans);
1640 if (ptrans == NULL) {
1641 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1643 "Failed to create transaction pool");
1644 signal_threads(ST_GRACEFUL);
1648 apr_pool_tag(ptrans, "transaction");
1650 get_worker(&have_idle_worker, 1, &workers_were_busy);
1651 rc = lr->accept_func(&csd, lr, ptrans);
1653 /* later we trash rv and rely on csd to indicate
1656 AP_DEBUG_ASSERT(rc == APR_SUCCESS || !csd);
1658 if (rc == APR_EGENERAL) {
1659 /* E[NM]FILE, ENOMEM, etc */
1660 resource_shortage = 1;
1661 signal_threads(ST_GRACEFUL);
1665 rc = ap_queue_push(worker_queue, csd, NULL, ptrans);
1666 if (rc != APR_SUCCESS) {
1667 /* trash the connection; we couldn't queue the connected
1668 * socket to a worker
1670 apr_socket_close(csd);
1671 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1673 "ap_queue_push failed");
1674 apr_pool_clear(ptrans);
1675 ap_push_pool(worker_queue_info, ptrans);
1678 have_idle_worker = 0;
1682 apr_pool_clear(ptrans);
1683 ap_push_pool(worker_queue_info, ptrans);
1686 } /* if:else on pt->type */
1688 else if (pt->type == PT_SERF) {
1689 /* send socket to serf. */
1690 /* XXXX: this doesn't require get_worker() */
1691 serf_event_trigger(g_serf, pt->baton, out_pfd);
1696 } /* while for processing poll */
1699 /* TODO: break out to separate function */
1702 for (i = 0; i < threads_per_child; i++) {
1703 ap_equeue_t *eq = worker_equeues[i];
1704 pollset_op_t *op = NULL;
1706 while ((op = ap_equeue_reader_next(eq)) != NULL) {
1712 /* XXX possible optimization: stash the current time for use as
1713 * r->request_time for new requests
1715 now = apr_time_now();
1716 /* we only do this once per 0.1s (TIMEOUT_FUDGE_FACTOR) */
1717 if (now > timeout_time) {
1718 struct process_score *ps;
1719 timeout_time = now + TIMEOUT_FUDGE_FACTOR;
1721 /* handle timed out sockets */
1723 /* Step 1: keepalive timeouts */
1724 /* If all workers are busy, we kill older keep-alive connections so that they
1725 * may connect to another process.
1727 if (workers_were_busy && keepalive_q.count) {
1728 ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
1729 "All workers are busy, will close %d keep-alive "
1732 process_timeout_queue(&keepalive_q,
1733 timeout_time + ap_server_conf->keep_alive_timeout,
1734 start_lingering_close);
1737 process_timeout_queue(&keepalive_q, timeout_time,
1738 start_lingering_close);
1740 /* Step 2: write completion timeouts */
1741 process_timeout_queue(&write_completion_q, timeout_time, start_lingering_close);
1742 /* Step 3: (normal) lingering close completion timeouts */
1743 process_timeout_queue(&linger_q, timeout_time, stop_lingering_close);
1744 /* Step 4: (short) lingering close completion timeouts */
1745 process_timeout_queue(&short_linger_q, timeout_time, stop_lingering_close);
1747 ps = ap_get_scoreboard_process(process_slot);
1748 ps->write_completion = write_completion_q.count;
1749 ps->lingering_close = linger_q.count + short_linger_q.count;
1750 ps->keep_alive = keepalive_q.count;
1752 ps->connections = apr_atomic_read32(&connection_count);
1753 /* XXX: should count CONN_STATE_SUSPENDED and set ps->suspended */
1755 if (listeners_disabled && !workers_were_busy &&
1756 (int)apr_atomic_read32(&connection_count) <
1757 ((int)ap_queue_info_get_idlers(worker_queue_info) - 1) *
1758 worker_factor / WORKER_FACTOR_SCALE + threads_per_child)
1760 listeners_disabled = 0;
1761 enable_listensocks(process_slot);
1764 * XXX: do we need to set some timeout that re-enables the listensocks
1765 * XXX: in case no other event occurs?
1767 } /* listener main loop */
1769 close_listeners(process_slot, &closed);
1770 ap_queue_term(worker_queue);
1772 apr_thread_exit(thd, APR_SUCCESS);
1776 /* XXX For ungraceful termination/restart, we definitely don't want to
1777 * wait for active connections to finish but we may want to wait
1778 * for idle workers to get out of the queue code and release mutexes,
1779 * since those mutexes are cleaned up pretty soon and some systems
1780 * may not react favorably (i.e., segfault) if operations are attempted
1781 * on cleaned-up mutexes.
1783 static void *APR_THREAD_FUNC worker_thread(apr_thread_t * thd, void *dummy)
1785 proc_info *ti = dummy;
1786 int process_slot = ti->pid;
1787 int thread_slot = ti->tid;
1788 apr_socket_t *csd = NULL;
1789 event_conn_state_t *cs;
1790 apr_pool_t *ptrans; /* Pool for per-transaction stuff */
1793 timer_event_t *te = NULL;
1794 ap_equeue_t *eq = worker_equeues[thread_slot];
1798 ap_scoreboard_image->servers[process_slot][thread_slot].pid = ap_my_pid;
1799 ap_scoreboard_image->servers[process_slot][thread_slot].tid = apr_os_thread_current();
1800 ap_scoreboard_image->servers[process_slot][thread_slot].generation = retained->my_generation;
1801 ap_update_child_status_from_indexes(process_slot, thread_slot,
1802 SERVER_STARTING, NULL);
1804 while (!workers_may_exit) {
1806 rv = ap_queue_info_set_idle(worker_queue_info, NULL);
1807 if (rv != APR_SUCCESS) {
1808 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
1809 "ap_queue_info_set_idle failed. Attempting to "
1810 "shutdown process gracefully.");
1811 signal_threads(ST_GRACEFUL);
1817 ap_update_child_status_from_indexes(process_slot, thread_slot,
1818 dying ? SERVER_GRACEFUL : SERVER_READY, NULL);
1820 if (workers_may_exit) {
1825 rv = ap_queue_pop_something(worker_queue, &csd, &cs, &ptrans, &te);
1827 if (rv != APR_SUCCESS) {
1828 /* We get APR_EOF during a graceful shutdown once all the
1829 * connections accepted by this server process have been handled.
1831 if (APR_STATUS_IS_EOF(rv)) {
1834 /* We get APR_EINTR whenever ap_queue_pop() has been interrupted
1835 * from an explicit call to ap_queue_interrupt_all(). This allows
1836 * us to unblock threads stuck in ap_queue_pop() when a shutdown
1839 * If workers_may_exit is set and this is ungraceful termination/
1840 * restart, we are bound to get an error on some systems (e.g.,
1841 * AIX, which sanity-checks mutex operations) since the queue
1842 * may have already been cleaned up. Don't log the "error" if
1843 * workers_may_exit is set.
1845 else if (APR_STATUS_IS_EINTR(rv)) {
1848 /* We got some other error. */
1849 else if (!workers_may_exit) {
1850 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1851 "ap_queue_pop failed");
1856 te->cbfunc(te->baton);
1859 apr_thread_mutex_lock(g_timer_ring_mtx);
1860 APR_RING_INSERT_TAIL(&timer_free_ring, te, timer_event_t, link);
1861 apr_thread_mutex_unlock(g_timer_ring_mtx);
1866 worker_sockets[thread_slot] = csd;
1867 rv = process_socket(thd, ptrans, csd, cs, eq, process_slot, thread_slot);
1869 requests_this_child--;
1871 worker_sockets[thread_slot] = NULL;
1875 ap_update_child_status_from_indexes(process_slot, thread_slot,
1876 dying ? SERVER_DEAD :
1878 (request_rec *) NULL);
1880 apr_thread_exit(thd, APR_SUCCESS);
1884 static int check_signal(int signum)
1896 static void create_listener_thread(thread_starter * ts)
1898 int my_child_num = ts->child_num_arg;
1899 apr_threadattr_t *thread_attr = ts->threadattr;
1903 my_info = (proc_info *) ap_malloc(sizeof(proc_info));
1904 my_info->pid = my_child_num;
1905 my_info->tid = -1; /* listener thread doesn't have a thread slot */
1907 rv = apr_thread_create(&ts->listener, thread_attr, listener_thread,
1909 if (rv != APR_SUCCESS) {
1910 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1911 "apr_thread_create: unable to create listener thread");
1912 /* let the parent decide how bad this really is */
1913 clean_child_exit(APEXIT_CHILDSICK);
1915 apr_os_thread_get(&listener_os_thread, ts->listener);
1918 /* XXX under some circumstances not understood, children can get stuck
1919 * in start_threads forever trying to take over slots which will
1920 * never be cleaned up; for now there is an APLOG_DEBUG message issued
1921 * every so often when this condition occurs
1923 static void *APR_THREAD_FUNC start_threads(apr_thread_t * thd, void *dummy)
1925 thread_starter *ts = dummy;
1926 apr_thread_t **threads = ts->threads;
1927 apr_threadattr_t *thread_attr = ts->threadattr;
1928 int child_num_arg = ts->child_num_arg;
1929 int my_child_num = child_num_arg;
1933 int threads_created = 0;
1934 int listener_started = 0;
1936 int prev_threads_created;
1937 int max_recycled_pools = -1;
1939 /* We must create the fd queues before we start up the listener
1940 * and worker threads. */
1941 worker_queue = apr_pcalloc(pchild, sizeof(*worker_queue));
1942 rv = ap_queue_init(worker_queue, threads_per_child, pchild);
1943 if (rv != APR_SUCCESS) {
1944 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1945 "ap_queue_init() failed");
1946 clean_child_exit(APEXIT_CHILDFATAL);
1949 if (ap_max_mem_free != APR_ALLOCATOR_MAX_FREE_UNLIMITED) {
1950 /* If we want to conserve memory, let's not keep an unlimited number of
1951 * pools & allocators.
1952 * XXX: This should probably be a separate config directive
1954 max_recycled_pools = threads_per_child * 3 / 4 ;
1956 rv = ap_queue_info_create(&worker_queue_info, pchild,
1957 threads_per_child, max_recycled_pools);
1958 if (rv != APR_SUCCESS) {
1959 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1960 "ap_queue_info_create() failed");
1961 clean_child_exit(APEXIT_CHILDFATAL);
1964 /* Create the main pollset */
1965 rv = apr_pollset_create(&event_pollset,
1966 threads_per_child, /* XXX don't we need more, to handle
1967 * connections in K-A or lingering
1970 pchild, APR_POLLSET_WAKEABLE|APR_POLLSET_NOCOPY);
1971 if (rv != APR_SUCCESS) {
1972 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
1973 "apr_pollset_create failed; check system or user limits");
1974 clean_child_exit(APEXIT_CHILDFATAL);
1977 worker_sockets = apr_pcalloc(pchild, threads_per_child
1978 * sizeof(apr_socket_t *));
1980 worker_equeues = apr_palloc(pchild, threads_per_child * sizeof(ap_equeue_t*));
1982 for (i = 0; i < threads_per_child; i++) {
1983 ap_equeue_t* eq = NULL;
1984 /* TODO: research/test optimal size of queue here */
1985 ap_equeue_create(pchild, 16, sizeof(pollset_op_t), &eq);
1986 /* same as thread ID */
1987 worker_equeues[i] = eq;
1990 loops = prev_threads_created = 0;
1992 /* threads_per_child does not include the listener thread */
1993 for (i = 0; i < threads_per_child; i++) {
1995 ap_scoreboard_image->servers[child_num_arg][i].status;
1997 if (status != SERVER_GRACEFUL && status != SERVER_DEAD) {
2001 my_info = (proc_info *) ap_malloc(sizeof(proc_info));
2002 my_info->pid = my_child_num;
2006 /* We are creating threads right now */
2007 ap_update_child_status_from_indexes(my_child_num, i,
2008 SERVER_STARTING, NULL);
2009 /* We let each thread update its own scoreboard entry. This is
2010 * done because it lets us deal with tid better.
2012 rv = apr_thread_create(&threads[i], thread_attr,
2013 worker_thread, my_info, pchild);
2014 if (rv != APR_SUCCESS) {
2015 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
2016 "apr_thread_create: unable to create worker thread");
2017 /* let the parent decide how bad this really is */
2018 clean_child_exit(APEXIT_CHILDSICK);
2023 /* Start the listener only when there are workers available */
2024 if (!listener_started && threads_created) {
2025 create_listener_thread(ts);
2026 listener_started = 1;
2030 if (start_thread_may_exit || threads_created == threads_per_child) {
2033 /* wait for previous generation to clean up an entry */
2034 apr_sleep(apr_time_from_sec(1));
2036 if (loops % 120 == 0) { /* every couple of minutes */
2037 if (prev_threads_created == threads_created) {
2038 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
2039 "child %" APR_PID_T_FMT " isn't taking over "
2040 "slots very quickly (%d of %d)",
2041 ap_my_pid, threads_created,
2044 prev_threads_created = threads_created;
2048 /* What state should this child_main process be listed as in the
2050 * ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING,
2051 * (request_rec *) NULL);
2053 * This state should be listed separately in the scoreboard, in some kind
2054 * of process_status, not mixed in with the worker threads' status.
2055 * "life_status" is almost right, but it's in the worker's structure, and
2056 * the name could be clearer. gla
2058 apr_thread_exit(thd, APR_SUCCESS);
2062 static void join_workers(apr_thread_t * listener, apr_thread_t ** threads)
2065 apr_status_t rv, thread_rv;
2070 /* deal with a rare timing window which affects waking up the
2071 * listener thread... if the signal sent to the listener thread
2072 * is delivered between the time it verifies that the
2073 * listener_may_exit flag is clear and the time it enters a
2074 * blocking syscall, the signal didn't do any good... work around
2075 * that by sleeping briefly and sending it again
2079 while (iter < 10 && !dying) {
2080 /* listener has not stopped accepting yet */
2081 apr_sleep(apr_time_make(0, 500000));
2086 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
2087 "the listener thread didn't stop accepting");
2090 rv = apr_thread_join(&thread_rv, listener);
2091 if (rv != APR_SUCCESS) {
2092 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
2093 "apr_thread_join: unable to join listener thread");
2098 for (i = 0; i < threads_per_child; i++) {
2099 if (threads[i]) { /* if we ever created this thread */
2100 rv = apr_thread_join(&thread_rv, threads[i]);
2101 if (rv != APR_SUCCESS) {
2102 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
2103 "apr_thread_join: unable to join worker "
2110 static void join_start_thread(apr_thread_t * start_thread_id)
2112 apr_status_t rv, thread_rv;
2114 start_thread_may_exit = 1; /* tell it to give up in case it is still
2115 * trying to take over slots from a
2116 * previous generation
2118 rv = apr_thread_join(&thread_rv, start_thread_id);
2119 if (rv != APR_SUCCESS) {
2120 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
2121 "apr_thread_join: unable to join the start " "thread");
2125 static void child_main(int child_num_arg)
2127 apr_thread_t **threads;
2130 apr_threadattr_t *thread_attr;
2131 apr_thread_t *start_thread_id;
2133 mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
2136 ap_my_pid = getpid();
2137 ap_fatal_signal_child_setup(ap_server_conf);
2138 apr_pool_create(&pchild, pconf);
2140 /*stuff to do before we switch id's, so we have permissions. */
2141 ap_reopen_scoreboard(pchild, NULL, 0);
2143 if (ap_run_drop_privileges(pchild, ap_server_conf)) {
2144 clean_child_exit(APEXIT_CHILDFATAL);
2147 apr_thread_mutex_create(&g_timer_ring_mtx, APR_THREAD_MUTEX_DEFAULT, pchild);
2148 APR_RING_INIT(&timer_free_ring, timer_event_t, link);
2149 APR_RING_INIT(&timer_ring, timer_event_t, link);
2150 ap_run_child_init(pchild, ap_server_conf);
2152 /* done with init critical section */
2154 /* Just use the standard apr_setup_signal_thread to block all signals
2155 * from being received. The child processes no longer use signals for
2156 * any communication with the parent process.
2158 rv = apr_setup_signal_thread();
2159 if (rv != APR_SUCCESS) {
2160 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
2161 "Couldn't initialize signal thread");
2162 clean_child_exit(APEXIT_CHILDFATAL);
2165 if (ap_max_requests_per_child) {
2166 requests_this_child = ap_max_requests_per_child;
2169 /* coding a value of zero means infinity */
2170 requests_this_child = INT_MAX;
2173 /* Setup worker threads */
2175 /* clear the storage; we may not create all our threads immediately,
2176 * and we want a 0 entry to indicate a thread which was not created
2178 threads = ap_calloc(threads_per_child, sizeof(apr_thread_t *));
2179 ts = apr_palloc(pchild, sizeof(*ts));
2181 apr_threadattr_create(&thread_attr, pchild);
2182 /* 0 means PTHREAD_CREATE_JOINABLE */
2183 apr_threadattr_detach_set(thread_attr, 0);
2185 if (ap_thread_stacksize != 0) {
2186 apr_threadattr_stacksize_set(thread_attr, ap_thread_stacksize);
2189 ts->threads = threads;
2190 ts->listener = NULL;
2191 ts->child_num_arg = child_num_arg;
2192 ts->threadattr = thread_attr;
2194 rv = apr_thread_create(&start_thread_id, thread_attr, start_threads,
2196 if (rv != APR_SUCCESS) {
2197 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
2198 "apr_thread_create: unable to create worker thread");
2199 /* let the parent decide how bad this really is */
2200 clean_child_exit(APEXIT_CHILDSICK);
2203 mpm_state = AP_MPMQ_RUNNING;
2205 /* If we are only running in one_process mode, we will want to
2206 * still handle signals. */
2208 /* Block until we get a terminating signal. */
2209 apr_signal_thread(check_signal);
2210 /* make sure the start thread has finished; signal_threads()
2211 * and join_workers() depend on that
2213 /* XXX join_start_thread() won't be awakened if one of our
2214 * threads encounters a critical error and attempts to
2215 * shutdown this child
2217 join_start_thread(start_thread_id);
2219 /* helps us terminate a little more quickly than the dispatch of the
2220 * signal thread; beats the Pipe of Death and the browsers
2222 signal_threads(ST_UNGRACEFUL);
2224 /* A terminating signal was received. Now join each of the
2225 * workers to clean them up.
2226 * If the worker already exited, then the join frees
2227 * their resources and returns.
2228 * If the worker hasn't exited, then this blocks until
2229 * they have (then cleans up).
2231 join_workers(ts->listener, threads);
2233 else { /* !one_process */
2234 /* remove SIGTERM from the set of blocked signals... if one of
2235 * the other threads in the process needs to take us down
2236 * (e.g., for MaxConnectionsPerChild) it will send us SIGTERM
2238 unblock_signal(SIGTERM);
2239 apr_signal(SIGTERM, dummy_signal_handler);
2240 /* Watch for any messages from the parent over the POD */
2242 rv = ap_event_pod_check(pod);
2243 if (rv == AP_NORESTART) {
2244 /* see if termination was triggered while we slept */
2245 switch (terminate_mode) {
2254 if (rv == AP_GRACEFUL || rv == AP_RESTART) {
2255 /* make sure the start thread has finished;
2256 * signal_threads() and join_workers depend on that
2258 join_start_thread(start_thread_id);
2259 signal_threads(rv ==
2260 AP_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL);
2265 /* A terminating signal was received. Now join each of the
2266 * workers to clean them up.
2267 * If the worker already exited, then the join frees
2268 * their resources and returns.
2269 * If the worker hasn't exited, then this blocks until
2270 * they have (then cleans up).
2272 join_workers(ts->listener, threads);
2277 clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0);
2280 static int make_child(server_rec * s, int slot)
2284 if (slot + 1 > retained->max_daemons_limit) {
2285 retained->max_daemons_limit = slot + 1;
2290 event_note_child_started(slot, getpid());
2295 if ((pid = fork()) == -1) {
2296 ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
2297 "fork: Unable to fork new process");
2299 /* fork didn't succeed. There's no need to touch the scoreboard;
2300 * if we were trying to replace a failed child process, then
2301 * server_main_loop() marked its workers SERVER_DEAD, and if
2302 * we were trying to replace a child process that exited normally,
2303 * its worker_thread()s left SERVER_DEAD or SERVER_GRACEFUL behind.
2306 /* In case system resources are maxxed out, we don't want
2307 Apache running away with the CPU trying to fork over and
2308 over and over again. */
2309 apr_sleep(apr_time_from_sec(10));
2315 #ifdef HAVE_BINDPROCESSOR
2316 /* By default, AIX binds to a single processor. This bit unbinds
2317 * children which will then bind to another CPU.
2319 int status = bindprocessor(BINDPROCESS, (int) getpid(),
2320 PROCESSOR_CLASS_ANY);
2322 ap_log_error(APLOG_MARK, APLOG_DEBUG, errno,
2324 "processor unbind failed");
2326 RAISE_SIGSTOP(MAKE_CHILD);
2328 apr_signal(SIGTERM, just_die);
2333 if (ap_scoreboard_image->parent[slot].pid != 0) {
2334 /* This new child process is squatting on the scoreboard
2335 * entry owned by an exiting child process, which cannot
2336 * exit until all active requests complete.
2338 event_note_child_lost_slot(slot, pid);
2340 ap_scoreboard_image->parent[slot].quiescing = 0;
2341 ap_scoreboard_image->parent[slot].not_accepting = 0;
2342 event_note_child_started(slot, pid);
2346 /* start up a bunch of children */
2347 static void startup_children(int number_to_start)
2351 for (i = 0; number_to_start && i < ap_daemons_limit; ++i) {
2352 if (ap_scoreboard_image->parent[i].pid != 0) {
2355 if (make_child(ap_server_conf, i) < 0) {
2362 static void perform_idle_server_maintenance(void)
2365 int idle_thread_count;
2369 int totally_free_length = 0;
2370 int free_slots[MAX_SPAWN_RATE];
2373 int active_thread_count = 0;
2375 /* initialize the free_list */
2378 idle_thread_count = 0;
2382 for (i = 0; i < ap_daemons_limit; ++i) {
2383 /* Initialization to satisfy the compiler. It doesn't know
2384 * that threads_per_child is always > 0 */
2385 int status = SERVER_DEAD;
2386 int any_dying_threads = 0;
2387 int any_dead_threads = 0;
2388 int all_dead_threads = 1;
2390 if (i >= retained->max_daemons_limit
2391 && totally_free_length == retained->idle_spawn_rate)
2392 /* short cut if all active processes have been examined and
2393 * enough empty scoreboard slots have been found
2397 ps = &ap_scoreboard_image->parent[i];
2398 for (j = 0; j < threads_per_child; j++) {
2399 ws = &ap_scoreboard_image->servers[i][j];
2400 status = ws->status;
2402 /* XXX any_dying_threads is probably no longer needed GLA */
2403 any_dying_threads = any_dying_threads ||
2404 (status == SERVER_GRACEFUL);
2405 any_dead_threads = any_dead_threads || (status == SERVER_DEAD);
2406 all_dead_threads = all_dead_threads &&
2407 (status == SERVER_DEAD || status == SERVER_GRACEFUL);
2409 /* We consider a starting server as idle because we started it
2410 * at least a cycle ago, and if it still hasn't finished starting
2411 * then we're just going to swamp things worse by forking more.
2412 * So we hopefully won't need to fork more if we count it.
2413 * This depends on the ordering of SERVER_READY and SERVER_STARTING.
2415 if (ps->pid != 0) { /* XXX just set all_dead_threads in outer
2416 for loop if no pid? not much else matters */
2417 if (status <= SERVER_READY && !ps->quiescing && !ps->not_accepting
2418 && ps->generation == retained->my_generation)
2420 ++idle_thread_count;
2422 if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
2423 ++active_thread_count;
2427 if (any_dead_threads
2428 && totally_free_length < retained->idle_spawn_rate
2429 && free_length < MAX_SPAWN_RATE
2430 && (!ps->pid /* no process in the slot */
2431 || ps->quiescing)) { /* or at least one is going away */
2432 if (all_dead_threads) {
2433 /* great! we prefer these, because the new process can
2434 * start more threads sooner. So prioritize this slot
2435 * by putting it ahead of any slots with active threads.
2437 * first, make room by moving a slot that's potentially still
2438 * in use to the end of the array
2440 free_slots[free_length] = free_slots[totally_free_length];
2441 free_slots[totally_free_length++] = i;
2444 /* slot is still in use - back of the bus
2446 free_slots[free_length] = i;
2450 /* XXX if (!ps->quiescing) is probably more reliable GLA */
2451 if (!any_dying_threads) {
2457 if (retained->sick_child_detected) {
2458 if (active_thread_count > 0) {
2459 /* some child processes appear to be working. don't kill the
2462 retained->sick_child_detected = 0;
2465 /* looks like a basket case. give up.
2467 shutdown_pending = 1;
2469 ap_log_error(APLOG_MARK, APLOG_ALERT, 0,
2471 "No active workers found..."
2472 " Apache is exiting!");
2473 /* the child already logged the failure details */
2478 retained->max_daemons_limit = last_non_dead + 1;
2480 if (idle_thread_count > max_spare_threads) {
2481 /* Kill off one child */
2482 ap_event_pod_signal(pod, TRUE);
2483 retained->idle_spawn_rate = 1;
2485 else if (idle_thread_count < min_spare_threads) {
2486 /* terminate the free list */
2487 if (free_length == 0) { /* scoreboard is full, can't fork */
2489 if (active_thread_count >= ap_daemons_limit * threads_per_child) {
2490 if (!retained->maxclients_reported) {
2491 /* only report this condition once */
2492 ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
2493 "server reached MaxRequestWorkers setting, "
2494 "consider raising the MaxRequestWorkers "
2496 retained->maxclients_reported = 1;
2500 ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
2501 "scoreboard is full, not at MaxRequestWorkers");
2503 retained->idle_spawn_rate = 1;
2506 if (free_length > retained->idle_spawn_rate) {
2507 free_length = retained->idle_spawn_rate;
2509 if (retained->idle_spawn_rate >= 8) {
2510 ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
2511 "server seems busy, (you may need "
2512 "to increase StartServers, ThreadsPerChild "
2513 "or Min/MaxSpareThreads), "
2514 "spawning %d children, there are around %d idle "
2515 "threads, and %d total children", free_length,
2516 idle_thread_count, total_non_dead);
2518 for (i = 0; i < free_length; ++i) {
2519 make_child(ap_server_conf, free_slots[i]);
2521 /* the next time around we want to spawn twice as many if this
2522 * wasn't good enough, but not if we've just done a graceful
2524 if (retained->hold_off_on_exponential_spawning) {
2525 --retained->hold_off_on_exponential_spawning;
2527 else if (retained->idle_spawn_rate < MAX_SPAWN_RATE) {
2528 retained->idle_spawn_rate *= 2;
2533 retained->idle_spawn_rate = 1;
2537 static void server_main_loop(int remaining_children_to_start)
2539 ap_generation_t old_gen;
2541 apr_exit_why_e exitwhy;
2542 int status, processed_status;
2546 while (!restart_pending && !shutdown_pending) {
2547 ap_wait_or_timeout(&exitwhy, &status, &pid, pconf, ap_server_conf);
2549 if (pid.pid != -1) {
2550 processed_status = ap_process_child_status(&pid, exitwhy, status);
2551 child_slot = ap_find_child_by_pid(&pid);
2552 if (processed_status == APEXIT_CHILDFATAL) {
2553 /* fix race condition found in PR 39311
2554 * A child created at the same time as a graceful happens
2555 * can find the lock missing and create a fatal error.
2556 * It is not fatal for the last generation to be in this state.
2559 || ap_get_scoreboard_process(child_slot)->generation
2560 == retained->my_generation) {
2561 shutdown_pending = 1;
2566 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf,
2567 "Ignoring fatal error in child of previous "
2568 "generation (pid %ld).",
2570 retained->sick_child_detected = 1;
2573 else if (processed_status == APEXIT_CHILDSICK) {
2574 /* tell perform_idle_server_maintenance to check into this
2575 * on the next timer pop
2577 retained->sick_child_detected = 1;
2579 /* non-fatal death... note that it's gone in the scoreboard. */
2580 if (child_slot >= 0) {
2581 for (i = 0; i < threads_per_child; i++)
2582 ap_update_child_status_from_indexes(child_slot, i,
2584 (request_rec *) NULL);
2586 event_note_child_killed(child_slot, 0, 0);
2587 ap_scoreboard_image->parent[child_slot].quiescing = 0;
2588 if (processed_status == APEXIT_CHILDSICK) {
2589 /* resource shortage, minimize the fork rate */
2590 retained->idle_spawn_rate = 1;
2592 else if (remaining_children_to_start
2593 && child_slot < ap_daemons_limit) {
2594 /* we're still doing a 1-for-1 replacement of dead
2595 * children with new children
2597 make_child(ap_server_conf, child_slot);
2598 --remaining_children_to_start;
2601 else if (ap_unregister_extra_mpm_process(pid.pid, &old_gen) == 1) {
2603 event_note_child_killed(-1, /* already out of the scoreboard */
2605 #if APR_HAS_OTHER_CHILD
2607 else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH,
2612 else if (retained->is_graceful) {
2613 /* Great, we've probably just lost a slot in the
2614 * scoreboard. Somehow we don't know about this child.
2616 ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
2618 "long lost child came home! (pid %ld)",
2621 /* Don't perform idle maintenance when a child dies,
2622 * only do it when there's a timeout. Remember only a
2623 * finite number of children can die, and it's pretty
2624 * pathological for a lot to die suddenly.
2628 else if (remaining_children_to_start) {
2629 /* we hit a 1 second timeout in which none of the previous
2630 * generation of children needed to be reaped... so assume
2631 * they're all done, and pick up the slack if any is left.
2633 startup_children(remaining_children_to_start);
2634 remaining_children_to_start = 0;
2635 /* In any event we really shouldn't do the code below because
2636 * few of the servers we just started are in the IDLE state
2637 * yet, so we'd mistakenly create an extra server.
2642 perform_idle_server_maintenance();
2646 static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
2648 int remaining_children_to_start;
2650 ap_log_pid(pconf, ap_pid_fname);
2652 if (!retained->is_graceful) {
2653 if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
2654 mpm_state = AP_MPMQ_STOPPING;
2657 /* fix the generation number in the global score; we just got a new,
2658 * cleared scoreboard
2660 ap_scoreboard_image->global->running_generation = retained->my_generation;
2663 restart_pending = shutdown_pending = 0;
2665 /* Don't thrash... */
2666 if (max_spare_threads < min_spare_threads + threads_per_child)
2667 max_spare_threads = min_spare_threads + threads_per_child;
2669 /* If we're doing a graceful_restart then we're going to see a lot
2670 * of children exiting immediately when we get into the main loop
2671 * below (because we just sent them AP_SIG_GRACEFUL). This happens pretty
2672 * rapidly... and for each one that exits we may start a new one, until
2673 * there are at least min_spare_threads idle threads, counting across
2674 * all children. But we may be permitted to start more children than
2675 * that, so we'll just keep track of how many we're
2676 * supposed to start up without the 1 second penalty between each fork.
2678 remaining_children_to_start = ap_daemons_to_start;
2679 if (remaining_children_to_start > ap_daemons_limit) {
2680 remaining_children_to_start = ap_daemons_limit;
2682 if (!retained->is_graceful) {
2683 startup_children(remaining_children_to_start);
2684 remaining_children_to_start = 0;
2687 /* give the system some time to recover before kicking into
2688 * exponential mode */
2689 retained->hold_off_on_exponential_spawning = 10;
2692 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2693 "%s configured -- resuming normal operations",
2694 ap_get_server_description());
2695 ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
2696 "Server built: %s", ap_get_server_built());
2697 ap_log_command_line(plog, s);
2699 mpm_state = AP_MPMQ_RUNNING;
2701 server_main_loop(remaining_children_to_start);
2702 mpm_state = AP_MPMQ_STOPPING;
2704 if (shutdown_pending && !retained->is_graceful) {
2705 /* Time to shut down:
2706 * Kill child processes, tell them to call child_exit, etc...
2708 ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
2709 ap_reclaim_child_processes(1, /* Start with SIGTERM */
2710 event_note_child_killed);
2713 /* cleanup pid file on normal shutdown */
2714 ap_remove_pid(pconf, ap_pid_fname);
2715 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,
2716 ap_server_conf, "caught SIGTERM, shutting down");
2719 } else if (shutdown_pending) {
2720 /* Time to gracefully shut down:
2721 * Kill child processes, tell them to call child_exit, etc...
2723 int active_children;
2725 apr_time_t cutoff = 0;
2727 /* Close our listeners, and then ask our children to do same */
2728 ap_close_listeners();
2729 ap_event_pod_killpg(pod, ap_daemons_limit, TRUE);
2730 ap_relieve_child_processes(event_note_child_killed);
2733 /* cleanup pid file on normal shutdown */
2734 ap_remove_pid(pconf, ap_pid_fname);
2735 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2736 "caught " AP_SIG_GRACEFUL_STOP_STRING
2737 ", shutting down gracefully");
2740 if (ap_graceful_shutdown_timeout) {
2741 cutoff = apr_time_now() +
2742 apr_time_from_sec(ap_graceful_shutdown_timeout);
2745 /* Don't really exit until each child has finished */
2746 shutdown_pending = 0;
2748 /* Pause for a second */
2749 apr_sleep(apr_time_from_sec(1));
2751 /* Relieve any children which have now exited */
2752 ap_relieve_child_processes(event_note_child_killed);
2754 active_children = 0;
2755 for (index = 0; index < ap_daemons_limit; ++index) {
2756 if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == APR_SUCCESS) {
2757 active_children = 1;
2758 /* Having just one child is enough to stay around */
2762 } while (!shutdown_pending && active_children &&
2763 (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
2765 /* We might be here because we received SIGTERM, either
2766 * way, try and make sure that all of our processes are
2769 ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
2770 ap_reclaim_child_processes(1, event_note_child_killed);
2775 /* we've been told to restart */
2776 apr_signal(SIGHUP, SIG_IGN);
2779 /* not worth thinking about */
2783 /* advance to the next generation */
2784 /* XXX: we really need to make sure this new generation number isn't in
2785 * use by any of the children.
2787 ++retained->my_generation;
2788 ap_scoreboard_image->global->running_generation = retained->my_generation;
2790 if (retained->is_graceful) {
2791 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2792 AP_SIG_GRACEFUL_STRING
2793 " received. Doing graceful restart");
2794 /* wake up the children...time to die. But we'll have more soon */
2795 ap_event_pod_killpg(pod, ap_daemons_limit, TRUE);
2798 /* This is mostly for debugging... so that we know what is still
2799 * gracefully dealing with existing request.
2804 /* Kill 'em all. Since the child acts the same on the parents SIGTERM
2805 * and a SIGHUP, we may as well use the same signal, because some user
2806 * pthreads are stealing signals from us left and right.
2808 ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
2810 ap_reclaim_child_processes(1, /* Start with SIGTERM */
2811 event_note_child_killed);
2812 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2813 "SIGHUP received. Attempting to restart");
2819 /* This really should be a post_config hook, but the error log is already
2820 * redirected by that point, so we need to do this in the open_logs phase.
2822 static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
2823 apr_pool_t * ptemp, server_rec * s)
2826 int level_flags = 0;
2831 /* the reverse of pre_config, we want this only the first time around */
2832 if (retained->module_loads == 1) {
2834 level_flags |= APLOG_STARTUP;
2837 if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {
2838 ap_log_error(APLOG_MARK, APLOG_ALERT | level_flags, 0,
2839 (startup ? NULL : s),
2840 "no listening sockets available, shutting down");
2845 if ((rv = ap_event_pod_open(pconf, &pod))) {
2846 ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
2847 (startup ? NULL : s),
2848 "could not open pipe-of-death");
2855 static int event_pre_config(apr_pool_t * pconf, apr_pool_t * plog,
2858 int no_detach, debug, foreground;
2860 const char *userdata_key = "mpm_event_module";
2862 mpm_state = AP_MPMQ_STARTING;
2864 debug = ap_exists_config_define("DEBUG");
2867 foreground = one_process = 1;
2871 one_process = ap_exists_config_define("ONE_PROCESS");
2872 no_detach = ap_exists_config_define("NO_DETACH");
2873 foreground = ap_exists_config_define("FOREGROUND");
2876 /* sigh, want this only the second time around */
2877 retained = ap_retained_data_get(userdata_key);
2879 retained = ap_retained_data_create(userdata_key, sizeof(*retained));
2880 retained->max_daemons_limit = -1;
2881 retained->idle_spawn_rate = 1;
2883 ++retained->module_loads;
2884 if (retained->module_loads == 2) {
2885 rv = apr_pollset_create(&event_pollset, 1, plog,
2886 APR_POLLSET_WAKEABLE|APR_POLLSET_NOCOPY);
2887 if (rv != APR_SUCCESS) {
2888 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,
2889 "apr_pollset_create failed; check system or user limits");
2890 return HTTP_INTERNAL_SERVER_ERROR;
2892 apr_pollset_destroy(event_pollset);
2894 if (!one_process && !foreground) {
2895 /* before we detach, setup crash handlers to log to errorlog */
2896 ap_fatal_signal_setup(ap_server_conf, pconf);
2897 rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND
2898 : APR_PROC_DETACH_DAEMONIZE);
2899 if (rv != APR_SUCCESS) {
2900 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,
2901 "apr_proc_detach failed");
2902 return HTTP_INTERNAL_SERVER_ERROR;
2907 parent_pid = ap_my_pid = getpid();
2909 ap_listen_pre_config();
2910 ap_daemons_to_start = DEFAULT_START_DAEMON;
2911 min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
2912 max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
2913 server_limit = DEFAULT_SERVER_LIMIT;
2914 thread_limit = DEFAULT_THREAD_LIMIT;
2915 ap_daemons_limit = server_limit;
2916 threads_per_child = DEFAULT_THREADS_PER_CHILD;
2917 max_workers = ap_daemons_limit * threads_per_child;
2918 ap_extended_status = 0;
2923 static int event_check_config(apr_pool_t *p, apr_pool_t *plog,
2924 apr_pool_t *ptemp, server_rec *s)
2928 /* the reverse of pre_config, we want this only the first time around */
2929 if (retained->module_loads == 1) {
2933 if (server_limit > MAX_SERVER_LIMIT) {
2935 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2936 "WARNING: ServerLimit of %d exceeds compile-time "
2937 "limit of", server_limit);
2938 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2939 " %d servers, decreasing to %d.",
2940 MAX_SERVER_LIMIT, MAX_SERVER_LIMIT);
2942 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2943 "ServerLimit of %d exceeds compile-time limit "
2944 "of %d, decreasing to match",
2945 server_limit, MAX_SERVER_LIMIT);
2947 server_limit = MAX_SERVER_LIMIT;
2949 else if (server_limit < 1) {
2951 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2952 "WARNING: ServerLimit of %d not allowed, "
2953 "increasing to 1.", server_limit);
2955 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2956 "ServerLimit of %d not allowed, increasing to 1",
2962 /* you cannot change ServerLimit across a restart; ignore
2965 if (!retained->first_server_limit) {
2966 retained->first_server_limit = server_limit;
2968 else if (server_limit != retained->first_server_limit) {
2969 /* don't need a startup console version here */
2970 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2971 "changing ServerLimit to %d from original value of %d "
2972 "not allowed during restart",
2973 server_limit, retained->first_server_limit);
2974 server_limit = retained->first_server_limit;
2977 if (thread_limit > MAX_THREAD_LIMIT) {
2979 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2980 "WARNING: ThreadLimit of %d exceeds compile-time "
2981 "limit of", thread_limit);
2982 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2983 " %d threads, decreasing to %d.",
2984 MAX_THREAD_LIMIT, MAX_THREAD_LIMIT);
2986 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2987 "ThreadLimit of %d exceeds compile-time limit "
2988 "of %d, decreasing to match",
2989 thread_limit, MAX_THREAD_LIMIT);
2991 thread_limit = MAX_THREAD_LIMIT;
2993 else if (thread_limit < 1) {
2995 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2996 "WARNING: ThreadLimit of %d not allowed, "
2997 "increasing to 1.", thread_limit);
2999 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3000 "ThreadLimit of %d not allowed, increasing to 1",
3006 /* you cannot change ThreadLimit across a restart; ignore
3009 if (!retained->first_thread_limit) {
3010 retained->first_thread_limit = thread_limit;
3012 else if (thread_limit != retained->first_thread_limit) {
3013 /* don't need a startup console version here */
3014 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3015 "changing ThreadLimit to %d from original value of %d "
3016 "not allowed during restart",
3017 thread_limit, retained->first_thread_limit);
3018 thread_limit = retained->first_thread_limit;
3021 if (threads_per_child > thread_limit) {
3023 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3024 "WARNING: ThreadsPerChild of %d exceeds ThreadLimit "
3025 "of", threads_per_child);
3026 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3027 " %d threads, decreasing to %d.",
3028 thread_limit, thread_limit);
3029 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3030 " To increase, please see the ThreadLimit "
3033 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3034 "ThreadsPerChild of %d exceeds ThreadLimit "
3035 "of %d, decreasing to match",
3036 threads_per_child, thread_limit);
3038 threads_per_child = thread_limit;
3040 else if (threads_per_child < 1) {
3042 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3043 "WARNING: ThreadsPerChild of %d not allowed, "
3044 "increasing to 1.", threads_per_child);
3046 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3047 "ThreadsPerChild of %d not allowed, increasing to 1",
3050 threads_per_child = 1;
3053 if (max_workers < threads_per_child) {
3055 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3056 "WARNING: MaxRequestWorkers of %d is less than "
3057 "ThreadsPerChild of", max_workers);
3058 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3059 " %d, increasing to %d. MaxRequestWorkers must be at "
3061 threads_per_child, threads_per_child);
3062 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3063 " as the number of threads in a single server.");
3065 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3066 "MaxRequestWorkers of %d is less than ThreadsPerChild "
3067 "of %d, increasing to match",
3068 max_workers, threads_per_child);
3070 max_workers = threads_per_child;
3073 ap_daemons_limit = max_workers / threads_per_child;
3075 if (max_workers % threads_per_child) {
3076 int tmp_max_workers = ap_daemons_limit * threads_per_child;
3079 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3080 "WARNING: MaxRequestWorkers of %d is not an integer "
3081 "multiple of", max_workers);
3082 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3083 " ThreadsPerChild of %d, decreasing to nearest "
3084 "multiple %d,", threads_per_child,
3086 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3087 " for a maximum of %d servers.",
3090 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3091 "MaxRequestWorkers of %d is not an integer multiple "
3092 "of ThreadsPerChild of %d, decreasing to nearest "
3093 "multiple %d", max_workers, threads_per_child,
3096 max_workers = tmp_max_workers;
3099 if (ap_daemons_limit > server_limit) {
3101 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3102 "WARNING: MaxRequestWorkers of %d would require %d "
3103 "servers and ", max_workers, ap_daemons_limit);
3104 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3105 " would exceed ServerLimit of %d, decreasing to %d.",
3106 server_limit, server_limit * threads_per_child);
3107 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3108 " To increase, please see the ServerLimit "
3111 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3112 "MaxRequestWorkers of %d would require %d servers and "
3113 "exceed ServerLimit of %d, decreasing to %d",
3114 max_workers, ap_daemons_limit, server_limit,
3115 server_limit * threads_per_child);
3117 ap_daemons_limit = server_limit;
3120 /* ap_daemons_to_start > ap_daemons_limit checked in ap_mpm_run() */
3121 if (ap_daemons_to_start < 0) {
3123 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3124 "WARNING: StartServers of %d not allowed, "
3125 "increasing to 1.", ap_daemons_to_start);
3127 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3128 "StartServers of %d not allowed, increasing to 1",
3129 ap_daemons_to_start);
3131 ap_daemons_to_start = 1;
3134 if (min_spare_threads < 1) {
3136 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3137 "WARNING: MinSpareThreads of %d not allowed, "
3138 "increasing to 1", min_spare_threads);
3139 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3140 " to avoid almost certain server failure.");
3141 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3142 " Please read the documentation.");
3144 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3145 "MinSpareThreads of %d not allowed, increasing to 1",
3148 min_spare_threads = 1;
3151 /* max_spare_threads < min_spare_threads + threads_per_child
3152 * checked in ap_mpm_run()
3158 static void event_hooks(apr_pool_t * p)
3160 /* Our open_logs hook function must run before the core's, or stderr
3161 * will be redirected to a file, and the messages won't print to the
3164 static const char *const aszSucc[] = { "core.c", NULL };
3167 ap_hook_open_logs(event_open_logs, NULL, aszSucc, APR_HOOK_REALLY_FIRST);
3168 /* we need to set the MPM state before other pre-config hooks use MPM query
3169 * to retrieve it, so register as REALLY_FIRST
3171 ap_hook_pre_config(event_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
3172 ap_hook_check_config(event_check_config, NULL, NULL, APR_HOOK_MIDDLE);
3173 ap_hook_mpm(event_run, NULL, NULL, APR_HOOK_MIDDLE);
3174 ap_hook_mpm_query(event_query, NULL, NULL, APR_HOOK_MIDDLE);
3175 ap_hook_mpm_register_timed_callback(event_register_timed_callback, NULL, NULL,
3177 ap_hook_mpm_get_name(event_get_name, NULL, NULL, APR_HOOK_MIDDLE);
3180 static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy,
3183 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3188 ap_daemons_to_start = atoi(arg);
3192 static const char *set_min_spare_threads(cmd_parms * cmd, void *dummy,
3195 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3200 min_spare_threads = atoi(arg);
3204 static const char *set_max_spare_threads(cmd_parms * cmd, void *dummy,
3207 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3212 max_spare_threads = atoi(arg);
3216 static const char *set_max_workers(cmd_parms * cmd, void *dummy,
3219 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3223 if (!strcasecmp(cmd->cmd->name, "MaxClients")) {
3224 ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL,
3225 "MaxClients is deprecated, use MaxRequestWorkers "
3228 max_workers = atoi(arg);
3232 static const char *set_threads_per_child(cmd_parms * cmd, void *dummy,
3235 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3240 threads_per_child = atoi(arg);
3243 static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg)
3245 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3250 server_limit = atoi(arg);
3254 static const char *set_thread_limit(cmd_parms * cmd, void *dummy,
3257 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3262 thread_limit = atoi(arg);
3266 static const char *set_worker_factor(cmd_parms * cmd, void *dummy,
3271 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3276 val = strtod(arg, &endptr);
3278 return "error parsing value";
3280 worker_factor = val * WORKER_FACTOR_SCALE;
3281 if (worker_factor == 0)
3287 static const command_rec event_cmds[] = {
3289 AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
3290 "Number of child processes launched at server startup"),
3291 AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF,
3292 "Maximum number of child processes for this run of Apache"),
3293 AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF,
3294 "Minimum number of idle threads, to handle request spikes"),
3295 AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF,
3296 "Maximum number of idle threads"),
3297 AP_INIT_TAKE1("MaxClients", set_max_workers, NULL, RSRC_CONF,
3298 "Deprecated name of MaxRequestWorkers"),
3299 AP_INIT_TAKE1("MaxRequestWorkers", set_max_workers, NULL, RSRC_CONF,
3300 "Maximum number of threads alive at the same time"),
3301 AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF,
3302 "Number of threads each child creates"),
3303 AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF,
3304 "Maximum number of worker threads per child process for this "
3305 "run of Apache - Upper limit for ThreadsPerChild"),
3306 AP_INIT_TAKE1("AsyncRequestWorkerFactor", set_worker_factor, NULL, RSRC_CONF,
3307 "How many additional connects will be accepted per idle "
3309 AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND,
3313 AP_DECLARE_MODULE(mpm_event) = {
3315 NULL, /* hook to run before apache parses args */
3316 NULL, /* create per-directory config structure */
3317 NULL, /* merge per-directory config structures */
3318 NULL, /* create per-server config structure */
3319 NULL, /* merge per-server config structures */
3320 event_cmds, /* command apr_table_t */
3321 event_hooks /* register_hooks */