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 */
101 #include "mod_serf.h"
105 /* Limit on the total --- clients will be locked out if more servers than
106 * this are needed. It is intended solely to keep the server from crashing
107 * when things get out of hand.
109 * We keep a hard maximum number of servers, for two reasons --- first off,
110 * in case something goes seriously wrong, we want to stop the fork bomb
111 * short of actually crashing the machine we're running on by filling some
112 * kernel table. Secondly, it keeps the size of the scoreboard file small
113 * enough that we can read the whole thing without worrying too much about
116 #ifndef DEFAULT_SERVER_LIMIT
117 #define DEFAULT_SERVER_LIMIT 16
120 /* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want
121 * some sort of compile-time limit to help catch typos.
123 #ifndef MAX_SERVER_LIMIT
124 #define MAX_SERVER_LIMIT 20000
127 /* Limit on the threads per process. Clients will be locked out if more than
130 * We keep this for one reason it keeps the size of the scoreboard file small
131 * enough that we can read the whole thing without worrying too much about
134 #ifndef DEFAULT_THREAD_LIMIT
135 #define DEFAULT_THREAD_LIMIT 64
138 /* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT. We want
139 * some sort of compile-time limit to help catch typos.
141 #ifndef MAX_THREAD_LIMIT
142 #define MAX_THREAD_LIMIT 100000
145 #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
147 #if !APR_VERSION_AT_LEAST(1,4,0)
148 #define apr_time_from_msec(x) (x * 1000)
151 #ifndef MAX_SECS_TO_LINGER
152 #define MAX_SECS_TO_LINGER 30
154 #define SECONDS_TO_LINGER 2
157 * Actual definitions of config globals
160 #ifndef DEFAULT_WORKER_FACTOR
161 #define DEFAULT_WORKER_FACTOR 2
163 #define WORKER_FACTOR_SCALE 16 /* scale factor to allow fractional values */
164 static unsigned int worker_factor = DEFAULT_WORKER_FACTOR * WORKER_FACTOR_SCALE;
166 static int threads_per_child = 0; /* Worker threads per child */
167 static int ap_daemons_to_start = 0;
168 static int min_spare_threads = 0;
169 static int max_spare_threads = 0;
170 static int ap_daemons_limit = 0;
171 static int max_workers = 0;
172 static int server_limit = 0;
173 static int thread_limit = 0;
174 static int dying = 0;
175 static int workers_may_exit = 0;
176 static int start_thread_may_exit = 0;
177 static int listener_may_exit = 0;
178 static int requests_this_child;
179 static int num_listensocks = 0;
180 static apr_uint32_t connection_count = 0;
181 static int resource_shortage = 0;
182 static fd_queue_t *worker_queue;
183 static fd_queue_info_t *worker_queue_info;
184 static int mpm_state = AP_MPMQ_STARTING;
186 static apr_thread_mutex_t *timeout_mutex;
187 APR_RING_HEAD(timeout_head_t, conn_state_t);
188 struct timeout_queue {
189 struct timeout_head_t head;
193 static struct timeout_queue write_completion_q, keepalive_q, linger_q,
195 static apr_pollfd_t *listener_pollfd;
198 * Macros for accessing struct timeout_queue.
199 * For TO_QUEUE_APPEND and TO_QUEUE_REMOVE, timeout_mutex must be held.
201 #define TO_QUEUE_APPEND(q, el) \
203 APR_RING_INSERT_TAIL(&(q).head, el, conn_state_t, timeout_list); \
207 #define TO_QUEUE_REMOVE(q, el) \
209 APR_RING_REMOVE(el, timeout_list); \
213 #define TO_QUEUE_INIT(q) \
215 APR_RING_INIT(&(q).head, conn_state_t, timeout_list); \
219 #define TO_QUEUE_ELEM_INIT(el) APR_RING_ELEM_INIT(el, timeout_list)
221 static apr_pollset_t *event_pollset;
225 apr_pollset_t *pollset;
229 static serf_context_t *g_serf;
232 /* The structure used to pass unique initialization info to each thread */
240 /* Structure used to pass information to the thread responsible for
241 * creating the rest of the threads.
245 apr_thread_t **threads;
246 apr_thread_t *listener;
248 apr_threadattr_t *threadattr;
264 } listener_poll_type;
266 /* data retained by event across load/unload of the module
267 * allocated on first call to pre-config hook; located on
268 * subsequent calls to pre-config hook
270 typedef struct event_retained_data {
271 int first_server_limit;
272 int first_thread_limit;
274 int sick_child_detected;
275 ap_generation_t my_generation;
276 int volatile is_graceful; /* set from signal handler */
277 int maxclients_reported;
279 * The max child slot ever assigned, preserved across restarts. Necessary
280 * to deal with MaxRequestWorkers changes across AP_SIG_GRACEFUL restarts.
281 * We use this value to optimize routines that have to scan the entire
284 int max_daemons_limit;
286 * idle_spawn_rate is the number of children that will be spawned on the
287 * next maintenance cycle if there aren't enough idle servers. It is
288 * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
289 * without the need to spawn.
292 #ifndef MAX_SPAWN_RATE
293 #define MAX_SPAWN_RATE (32)
295 int hold_off_on_exponential_spawning;
296 } event_retained_data;
297 static event_retained_data *retained;
299 #define ID_FROM_CHILD_THREAD(c, t) ((c * thread_limit) + t)
301 static ap_event_pod_t *pod;
303 /* The event MPM respects a couple of runtime flags that can aid
304 * in debugging. Setting the -DNO_DETACH flag will prevent the root process
305 * from detaching from its controlling terminal. Additionally, setting
306 * the -DONE_PROCESS flag (which implies -DNO_DETACH) will get you the
307 * child_main loop running in the process which originally started up.
308 * This gives you a pretty nice debugging environment. (You'll get a SIGHUP
309 * early in standalone_main; just continue through. This is the server
310 * trying to kill off any child processes which it might have lying
311 * around --- Apache doesn't keep track of their pids, it just sends
312 * SIGHUP to the process group, ignoring it in the root process.
313 * Continue through and you'll be fine.).
316 static int one_process = 0;
319 int raise_sigstop_flags;
322 static apr_pool_t *pconf; /* Pool for config stuff */
323 static apr_pool_t *pchild; /* Pool for httpd child stuff */
325 static pid_t ap_my_pid; /* Linux getpid() doesn't work except in main
326 thread. Use this instead */
327 static pid_t parent_pid;
328 static apr_os_thread_t *listener_os_thread;
330 /* The LISTENER_SIGNAL signal will be sent from the main thread to the
331 * listener thread to wake it up for graceful termination (what a child
332 * process from an old generation does when the admin does "apachectl
333 * graceful"). This signal will be blocked in all threads of a child
334 * process except for the listener thread.
336 #define LISTENER_SIGNAL SIGHUP
338 /* An array of socket descriptors in use by each thread used to
339 * perform a non-graceful (forced) shutdown of the server.
341 static apr_socket_t **worker_sockets;
343 static void disable_listensocks(int process_slot)
346 for (i = 0; i < num_listensocks; i++) {
347 apr_pollset_remove(event_pollset, &listener_pollfd[i]);
349 ap_scoreboard_image->parent[process_slot].not_accepting = 1;
352 static void enable_listensocks(int process_slot)
355 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
356 "Accepting new connections again: "
357 "%u active conns, %u idle workers",
358 apr_atomic_read32(&connection_count),
359 ap_queue_info_get_idlers(worker_queue_info));
360 for (i = 0; i < num_listensocks; i++)
361 apr_pollset_add(event_pollset, &listener_pollfd[i]);
363 * XXX: This is not yet optimal. If many workers suddenly become available,
364 * XXX: the parent may kill some processes off too soon.
366 ap_scoreboard_image->parent[process_slot].not_accepting = 0;
369 static void close_worker_sockets(void)
372 for (i = 0; i < threads_per_child; i++) {
373 if (worker_sockets[i]) {
374 apr_socket_close(worker_sockets[i]);
375 worker_sockets[i] = NULL;
380 static void wakeup_listener(void)
382 listener_may_exit = 1;
383 if (!listener_os_thread) {
384 /* XXX there is an obscure path that this doesn't handle perfectly:
385 * right after listener thread is created but before
386 * listener_os_thread is set, the first worker thread hits an
387 * error and starts graceful termination
392 /* unblock the listener if it's waiting for a worker */
393 ap_queue_info_term(worker_queue_info);
396 * we should just be able to "kill(ap_my_pid, LISTENER_SIGNAL)" on all
397 * platforms and wake up the listener thread since it is the only thread
398 * with SIGHUP unblocked, but that doesn't work on Linux
400 #ifdef HAVE_PTHREAD_KILL
401 pthread_kill(*listener_os_thread, LISTENER_SIGNAL);
403 kill(ap_my_pid, LISTENER_SIGNAL);
408 #define ST_GRACEFUL 1
409 #define ST_UNGRACEFUL 2
411 static int terminate_mode = ST_INIT;
413 static void signal_threads(int mode)
415 if (terminate_mode == mode) {
418 terminate_mode = mode;
419 mpm_state = AP_MPMQ_STOPPING;
421 /* in case we weren't called from the listener thread, wake up the
426 /* for ungraceful termination, let the workers exit now;
427 * for graceful termination, the listener thread will notify the
428 * workers to exit once it has stopped accepting new connections
430 if (mode == ST_UNGRACEFUL) {
431 workers_may_exit = 1;
432 ap_queue_interrupt_all(worker_queue);
433 close_worker_sockets(); /* forcefully kill all current connections */
437 static int event_query(int query_code, int *result, apr_status_t *rv)
440 switch (query_code) {
441 case AP_MPMQ_MAX_DAEMON_USED:
442 *result = retained->max_daemons_limit;
444 case AP_MPMQ_IS_THREADED:
445 *result = AP_MPMQ_STATIC;
447 case AP_MPMQ_IS_FORKED:
448 *result = AP_MPMQ_DYNAMIC;
450 case AP_MPMQ_IS_ASYNC:
453 case AP_MPMQ_HAS_SERF:
456 case AP_MPMQ_HARD_LIMIT_DAEMONS:
457 *result = server_limit;
459 case AP_MPMQ_HARD_LIMIT_THREADS:
460 *result = thread_limit;
462 case AP_MPMQ_MAX_THREADS:
463 *result = threads_per_child;
465 case AP_MPMQ_MIN_SPARE_DAEMONS:
468 case AP_MPMQ_MIN_SPARE_THREADS:
469 *result = min_spare_threads;
471 case AP_MPMQ_MAX_SPARE_DAEMONS:
474 case AP_MPMQ_MAX_SPARE_THREADS:
475 *result = max_spare_threads;
477 case AP_MPMQ_MAX_REQUESTS_DAEMON:
478 *result = ap_max_requests_per_child;
480 case AP_MPMQ_MAX_DAEMONS:
481 *result = ap_daemons_limit;
483 case AP_MPMQ_MPM_STATE:
486 case AP_MPMQ_GENERATION:
487 *result = retained->my_generation;
496 static void event_note_child_killed(int childnum, pid_t pid, ap_generation_t gen)
498 if (childnum != -1) { /* child had a scoreboard slot? */
499 ap_run_child_status(ap_server_conf,
500 ap_scoreboard_image->parent[childnum].pid,
501 ap_scoreboard_image->parent[childnum].generation,
502 childnum, MPM_CHILD_EXITED);
503 ap_scoreboard_image->parent[childnum].pid = 0;
506 ap_run_child_status(ap_server_conf, pid, gen, -1, MPM_CHILD_EXITED);
510 static void event_note_child_started(int slot, pid_t pid)
512 ap_scoreboard_image->parent[slot].pid = pid;
513 ap_run_child_status(ap_server_conf,
514 ap_scoreboard_image->parent[slot].pid,
515 retained->my_generation, slot, MPM_CHILD_STARTED);
518 static void event_note_child_lost_slot(int slot, pid_t newpid)
520 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
521 "pid %" APR_PID_T_FMT " taking over scoreboard slot from "
522 "%" APR_PID_T_FMT "%s",
524 ap_scoreboard_image->parent[slot].pid,
525 ap_scoreboard_image->parent[slot].quiescing ?
526 " (quiescing)" : "");
527 ap_run_child_status(ap_server_conf,
528 ap_scoreboard_image->parent[slot].pid,
529 ap_scoreboard_image->parent[slot].generation,
530 slot, MPM_CHILD_LOST_SLOT);
531 /* Don't forget about this exiting child process, or we
532 * won't be able to kill it if it doesn't exit by the
533 * time the server is shut down.
535 ap_register_extra_mpm_process(ap_scoreboard_image->parent[slot].pid,
536 ap_scoreboard_image->parent[slot].generation);
539 static const char *event_get_name(void)
544 /* a clean exit from a child with proper cleanup */
545 static void clean_child_exit(int code) __attribute__ ((noreturn));
546 static void clean_child_exit(int code)
548 mpm_state = AP_MPMQ_STOPPING;
550 apr_pool_destroy(pchild);
554 event_note_child_killed(/* slot */ 0, 0, 0);
560 static void just_die(int sig)
565 /*****************************************************************
566 * Connection structures and accounting...
569 static int child_fatal;
571 /* volatile because they're updated from a signal handler */
572 static int volatile shutdown_pending;
573 static int volatile restart_pending;
574 ap_generation_t volatile ap_my_generation = 0;
576 static apr_status_t decrement_connection_count(void *dummy) {
577 apr_atomic_dec32(&connection_count);
582 * ap_start_shutdown() and ap_start_restart(), below, are a first stab at
583 * functions to initiate shutdown or restart without relying on signals.
584 * Previously this was initiated in sig_term() and restart() signal handlers,
585 * but we want to be able to start a shutdown/restart from other sources --
586 * e.g. on Win32, from the service manager. Now the service manager can
587 * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that
588 * these functions can also be called by the child processes, since global
589 * variables are no longer used to pass on the required action to the parent.
591 * These should only be called from the parent process itself, since the
592 * parent process will use the shutdown_pending and restart_pending variables
593 * to determine whether to shutdown or restart. The child process should
594 * call signal_parent() directly to tell the parent to die -- this will
595 * cause neither of those variable to be set, which the parent will
596 * assume means something serious is wrong (which it will be, for the
597 * child to force an exit) and so do an exit anyway.
600 static void ap_start_shutdown(int graceful)
602 mpm_state = AP_MPMQ_STOPPING;
603 if (shutdown_pending == 1) {
604 /* Um, is this _probably_ not an error, if the user has
605 * tried to do a shutdown twice quickly, so we won't
606 * worry about reporting it.
610 shutdown_pending = 1;
611 retained->is_graceful = graceful;
614 /* do a graceful restart if graceful == 1 */
615 static void ap_start_restart(int graceful)
617 mpm_state = AP_MPMQ_STOPPING;
618 if (restart_pending == 1) {
619 /* Probably not an error - don't bother reporting it */
623 retained->is_graceful = graceful;
626 static void sig_term(int sig)
628 ap_start_shutdown(sig == AP_SIG_GRACEFUL_STOP);
631 static void restart(int sig)
633 ap_start_restart(sig == AP_SIG_GRACEFUL);
636 static void set_signals(void)
638 #ifndef NO_USE_SIGACTION
643 ap_fatal_signal_setup(ap_server_conf, pconf);
646 #ifndef NO_USE_SIGACTION
647 sigemptyset(&sa.sa_mask);
650 sa.sa_handler = sig_term;
651 if (sigaction(SIGTERM, &sa, NULL) < 0)
652 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
653 "sigaction(SIGTERM)");
654 #ifdef AP_SIG_GRACEFUL_STOP
655 if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0)
656 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
657 "sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")");
660 if (sigaction(SIGINT, &sa, NULL) < 0)
661 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
662 "sigaction(SIGINT)");
665 sa.sa_handler = SIG_DFL;
666 if (sigaction(SIGXCPU, &sa, NULL) < 0)
667 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
668 "sigaction(SIGXCPU)");
671 /* For systems following the LFS standard, ignoring SIGXFSZ allows
672 * a write() beyond the 2GB limit to fail gracefully with E2BIG
673 * rather than terminate the process. */
674 sa.sa_handler = SIG_IGN;
675 if (sigaction(SIGXFSZ, &sa, NULL) < 0)
676 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
677 "sigaction(SIGXFSZ)");
680 sa.sa_handler = SIG_IGN;
681 if (sigaction(SIGPIPE, &sa, NULL) < 0)
682 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
683 "sigaction(SIGPIPE)");
686 /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy
688 sigaddset(&sa.sa_mask, SIGHUP);
689 sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL);
690 sa.sa_handler = restart;
691 if (sigaction(SIGHUP, &sa, NULL) < 0)
692 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
693 "sigaction(SIGHUP)");
694 if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0)
695 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
696 "sigaction(" AP_SIG_GRACEFUL_STRING ")");
700 apr_signal(SIGXCPU, SIG_DFL);
703 apr_signal(SIGXFSZ, SIG_IGN);
707 apr_signal(SIGTERM, sig_term);
709 apr_signal(SIGHUP, restart);
711 #ifdef AP_SIG_GRACEFUL
712 apr_signal(AP_SIG_GRACEFUL, restart);
713 #endif /* AP_SIG_GRACEFUL */
714 #ifdef AP_SIG_GRACEFUL_STOP
715 apr_signal(AP_SIG_GRACEFUL_STOP, sig_term);
716 #endif /* AP_SIG_GRACEFUL_STOP */
718 apr_signal(SIGPIPE, SIG_IGN);
724 static int start_lingering_close(conn_state_t *cs)
727 if (ap_start_lingering_close(cs->c)) {
728 apr_pool_clear(cs->p);
729 ap_push_pool(worker_queue_info, cs->p);
733 apr_socket_t *csd = ap_get_conn_socket(cs->c);
734 struct timeout_queue *q;
736 rv = apr_socket_timeout_set(csd, 0);
737 AP_DEBUG_ASSERT(rv == APR_SUCCESS);
739 * If some module requested a shortened waiting period, only wait for
740 * 2s (SECONDS_TO_LINGER). This is useful for mitigating certain
743 if (apr_table_get(cs->c->notes, "short-lingering-close")) {
744 cs->expiration_time =
745 apr_time_now() + apr_time_from_sec(SECONDS_TO_LINGER);
747 cs->state = CONN_STATE_LINGER_SHORT;
750 cs->expiration_time =
751 apr_time_now() + apr_time_from_sec(MAX_SECS_TO_LINGER);
753 cs->state = CONN_STATE_LINGER_NORMAL;
755 apr_thread_mutex_lock(timeout_mutex);
756 TO_QUEUE_APPEND(*q, cs);
757 apr_thread_mutex_unlock(timeout_mutex);
758 cs->pfd.reqevents = APR_POLLIN | APR_POLLHUP | APR_POLLERR;
759 rv = apr_pollset_add(event_pollset, &cs->pfd);
760 if (rv != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rv)) {
761 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
762 "start_lingering_close: apr_pollset_add failure");
769 static int stop_lingering_close(conn_state_t *cs)
772 apr_socket_t *csd = ap_get_conn_socket(cs->c);
773 ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf,
774 "socket reached timeout in lingering-close state");
775 rv = apr_socket_close(csd);
776 if (rv != APR_SUCCESS) {
777 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, "error closing socket");
780 apr_pool_clear(cs->p);
781 ap_push_pool(worker_queue_info, cs->p);
787 /*****************************************************************
788 * Child process main loop.
791 static int process_socket(apr_thread_t *thd, apr_pool_t * p, apr_socket_t * sock,
792 conn_state_t * cs, int my_child_num,
796 long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num);
800 ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num);
802 if (cs == NULL) { /* This is a new connection */
803 listener_poll_type *pt = apr_pcalloc(p, sizeof(*pt));
804 cs = apr_pcalloc(p, sizeof(conn_state_t));
805 cs->bucket_alloc = apr_bucket_alloc_create(p);
806 c = ap_run_create_connection(p, ap_server_conf, sock,
807 conn_id, sbh, cs->bucket_alloc);
808 apr_atomic_inc32(&connection_count);
809 apr_pool_cleanup_register(c->pool, NULL, decrement_connection_count, apr_pool_cleanup_null);
810 c->current_thread = thd;
814 cs->pfd.desc_type = APR_POLL_SOCKET;
815 cs->pfd.reqevents = APR_POLLIN;
816 cs->pfd.desc.s = sock;
819 cs->pfd.client_data = pt;
820 TO_QUEUE_ELEM_INIT(cs);
822 ap_update_vhost_given_ip(c);
824 rc = ap_run_pre_connection(c, sock);
825 if (rc != OK && rc != DONE) {
826 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
827 "process_socket: connection aborted");
832 * XXX If the platform does not have a usable way of bundling
833 * accept() with a socket readability check, like Win32,
834 * and there are measurable delays before the
835 * socket is readable due to the first data packet arriving,
836 * it might be better to create the cs on the listener thread
837 * with the state set to CONN_STATE_CHECK_REQUEST_LINE_READABLE
839 * FreeBSD users will want to enable the HTTP accept filter
840 * module in their kernel for the highest performance
841 * When the accept filter is active, sockets are kept in the
842 * kernel until a HTTP request is received.
844 cs->state = CONN_STATE_READ_REQUEST_LINE;
850 c->current_thread = thd;
853 if (c->clogging_input_filters && !c->aborted) {
854 /* Since we have an input filter which 'cloggs' the input stream,
855 * like mod_ssl, lets just do the normal read from input filters,
856 * like the Worker MPM does.
858 ap_run_process_connection(c);
859 if (cs->state != CONN_STATE_SUSPENDED) {
860 cs->state = CONN_STATE_LINGER;
865 if (cs->state == CONN_STATE_READ_REQUEST_LINE) {
867 ap_run_process_connection(c);
869 /* state will be updated upon return
870 * fall thru to either wait for readability/timeout or
875 cs->state = CONN_STATE_LINGER;
879 if (cs->state == CONN_STATE_WRITE_COMPLETION) {
880 ap_filter_t *output_filter = c->output_filters;
882 ap_update_child_status_from_conn(sbh, SERVER_BUSY_WRITE, c);
883 while (output_filter->next != NULL) {
884 output_filter = output_filter->next;
886 rv = output_filter->frec->filter_func.out_func(output_filter, NULL);
887 if (rv != APR_SUCCESS) {
888 ap_log_cerror(APLOG_MARK, APLOG_WARNING, rv, c,
889 "network write failure in core output filter");
890 cs->state = CONN_STATE_LINGER;
892 else if (c->data_in_output_filters) {
893 /* Still in WRITE_COMPLETION_STATE:
894 * Set a write timeout for this connection, and let the
895 * event thread poll for writeability.
897 cs->expiration_time = ap_server_conf->timeout + apr_time_now();
898 apr_thread_mutex_lock(timeout_mutex);
899 TO_QUEUE_APPEND(write_completion_q, cs);
900 apr_thread_mutex_unlock(timeout_mutex);
901 cs->pfd.reqevents = APR_POLLOUT | APR_POLLHUP | APR_POLLERR;
902 rc = apr_pollset_add(event_pollset, &cs->pfd);
905 else if (c->keepalive != AP_CONN_KEEPALIVE || c->aborted ||
907 c->cs->state = CONN_STATE_LINGER;
909 else if (c->data_in_input_filters) {
910 cs->state = CONN_STATE_READ_REQUEST_LINE;
914 cs->state = CONN_STATE_CHECK_REQUEST_LINE_READABLE;
918 if (cs->state == CONN_STATE_LINGER) {
919 if (!start_lingering_close(cs))
922 else if (cs->state == CONN_STATE_CHECK_REQUEST_LINE_READABLE) {
925 /* It greatly simplifies the logic to use a single timeout value here
926 * because the new element can just be added to the end of the list and
927 * it will stay sorted in expiration time sequence. If brand new
928 * sockets are sent to the event thread for a readability check, this
929 * will be a slight behavior change - they use the non-keepalive
930 * timeout today. With a normal client, the socket will be readable in
931 * a few milliseconds anyway.
933 cs->expiration_time = ap_server_conf->keep_alive_timeout +
935 apr_thread_mutex_lock(timeout_mutex);
936 TO_QUEUE_APPEND(keepalive_q, cs);
937 apr_thread_mutex_unlock(timeout_mutex);
939 /* Add work to pollset. */
940 cs->pfd.reqevents = APR_POLLIN;
941 rc = apr_pollset_add(event_pollset, &cs->pfd);
943 if (rc != APR_SUCCESS) {
944 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
945 "process_socket: apr_pollset_add failure");
946 AP_DEBUG_ASSERT(rc == APR_SUCCESS);
952 /* requests_this_child has gone to zero or below. See if the admin coded
953 "MaxConnectionsPerChild 0", and keep going in that case. Doing it this way
954 simplifies the hot path in worker_thread */
955 static void check_infinite_requests(void)
957 if (ap_max_requests_per_child) {
958 signal_threads(ST_GRACEFUL);
961 requests_this_child = INT_MAX; /* keep going */
965 static void close_listeners(int process_slot, int *closed) {
968 disable_listensocks(process_slot);
969 ap_close_listeners();
972 ap_scoreboard_image->parent[process_slot].quiescing = 1;
973 for (i = 0; i < threads_per_child; ++i) {
974 ap_update_child_status_from_indexes(process_slot, i,
975 SERVER_GRACEFUL, NULL);
977 /* wake up the main thread */
978 kill(ap_my_pid, SIGTERM);
982 static void unblock_signal(int sig)
986 sigemptyset(&sig_mask);
987 sigaddset(&sig_mask, sig);
988 #if defined(SIGPROCMASK_SETS_THREAD_MASK)
989 sigprocmask(SIG_UNBLOCK, &sig_mask, NULL);
991 pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL);
995 static void dummy_signal_handler(int sig)
997 /* XXX If specifying SIG_IGN is guaranteed to unblock a syscall,
998 * then we don't need this goofy function.
1004 static apr_status_t s_socket_add(void *user_baton,
1008 s_baton_t *s = (s_baton_t*)user_baton;
1009 /* XXXXX: recycle listener_poll_types */
1010 listener_poll_type *pt = malloc(sizeof(*pt));
1012 pt->baton = serf_baton;
1013 pfd->client_data = pt;
1014 return apr_pollset_add(s->pollset, pfd);
1017 static apr_status_t s_socket_remove(void *user_baton,
1021 s_baton_t *s = (s_baton_t*)user_baton;
1022 listener_poll_type *pt = pfd->client_data;
1024 return apr_pollset_remove(s->pollset, pfd);
1028 static apr_status_t init_pollset(apr_pool_t *p)
1031 s_baton_t *baton = NULL;
1034 listener_poll_type *pt;
1037 TO_QUEUE_INIT(write_completion_q);
1038 TO_QUEUE_INIT(keepalive_q);
1039 TO_QUEUE_INIT(linger_q);
1040 TO_QUEUE_INIT(short_linger_q);
1042 listener_pollfd = apr_palloc(p, sizeof(apr_pollfd_t) * num_listensocks);
1043 for (lr = ap_listeners; lr != NULL; lr = lr->next, i++) {
1045 AP_DEBUG_ASSERT(i < num_listensocks);
1046 pfd = &listener_pollfd[i];
1047 pt = apr_pcalloc(p, sizeof(*pt));
1048 pfd->desc_type = APR_POLL_SOCKET;
1049 pfd->desc.s = lr->sd;
1050 pfd->reqevents = APR_POLLIN;
1052 pt->type = PT_ACCEPT;
1055 pfd->client_data = pt;
1057 apr_socket_opt_set(pfd->desc.s, APR_SO_NONBLOCK, 1);
1058 apr_pollset_add(event_pollset, pfd);
1060 lr->accept_func = ap_unixd_accept;
1064 baton = apr_pcalloc(p, sizeof(*baton));
1065 baton->pollset = event_pollset;
1066 /* TODO: subpools, threads, reuse, etc. -- currently use malloc() inside :( */
1069 g_serf = serf_context_create_ex(baton,
1071 s_socket_remove, p);
1073 ap_register_provider(p, "mpm_serf",
1074 "instance", "0", g_serf);
1081 static apr_status_t push_timer2worker(timer_event_t* te)
1083 return ap_queue_push_timer(worker_queue, te);
1086 static apr_status_t push2worker(const apr_pollfd_t * pfd,
1087 apr_pollset_t * pollset)
1089 listener_poll_type *pt = (listener_poll_type *) pfd->client_data;
1090 conn_state_t *cs = (conn_state_t *) pt->baton;
1093 rc = apr_pollset_remove(pollset, pfd);
1096 * Some of the pollset backends, like KQueue or Epoll
1097 * automagically remove the FD if the socket is closed,
1098 * therefore, we can accept _SUCCESS or _NOTFOUND,
1099 * and we still want to keep going
1101 if (rc != APR_SUCCESS && !APR_STATUS_IS_NOTFOUND(rc)) {
1102 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
1103 "pollset remove failed");
1104 start_lingering_close(cs);
1108 rc = ap_queue_push(worker_queue, cs->pfd.desc.s, cs, cs->p);
1109 if (rc != APR_SUCCESS) {
1110 /* trash the connection; we couldn't queue the connected
1111 * socket to a worker
1113 apr_bucket_alloc_destroy(cs->bucket_alloc);
1114 apr_socket_close(cs->pfd.desc.s);
1115 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1116 ap_server_conf, "push2worker: ap_queue_push failed");
1117 apr_pool_clear(cs->p);
1118 ap_push_pool(worker_queue_info, cs->p);
1125 * If *have_idle_worker_p == 0, reserve a worker thread, and set
1126 * *have_idle_worker_p = 1.
1127 * If *have_idle_worker_p is already 1, will do nothing.
1128 * If blocking == 1, block if all workers are currently busy.
1129 * If no worker was available immediately, will set *all_busy to 1.
1130 * XXX: If there are no workers, we should not block immediately but
1131 * XXX: close all keep-alive connections first.
1133 static void get_worker(int *have_idle_worker_p, int blocking, int *all_busy)
1137 if (*have_idle_worker_p) {
1138 /* already reserved a worker thread - must have hit a
1139 * transient error on a previous pass
1145 rc = ap_queue_info_wait_for_idler(worker_queue_info, all_busy);
1147 rc = ap_queue_info_try_get_idler(worker_queue_info);
1149 if (rc == APR_SUCCESS) {
1150 *have_idle_worker_p = 1;
1152 else if (!blocking && rc == APR_EAGAIN) {
1155 else if (!APR_STATUS_IS_EOF(rc)) {
1156 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
1157 "ap_queue_info_wait_for_idler failed. "
1158 "Attempting to shutdown process gracefully");
1159 signal_threads(ST_GRACEFUL);
1163 /* XXXXXX: Convert to skiplist or other better data structure
1164 * (yes, this is VERY VERY VERY VERY BAD)
1167 /* Structures to reuse */
1168 static APR_RING_HEAD(timer_free_ring_t, timer_event_t) timer_free_ring;
1170 static APR_RING_HEAD(timer_ring_t, timer_event_t) timer_ring;
1172 static apr_thread_mutex_t *g_timer_ring_mtx;
1174 static apr_status_t event_register_timed_callback(apr_time_t t,
1175 ap_mpm_callback_fn_t *cbfn,
1181 /* oh yeah, and make locking smarter/fine grained. */
1182 apr_thread_mutex_lock(g_timer_ring_mtx);
1184 if (!APR_RING_EMPTY(&timer_free_ring, timer_event_t, link)) {
1185 te = APR_RING_FIRST(&timer_free_ring);
1186 APR_RING_REMOVE(te, link);
1189 /* XXXXX: lol, pool allocation without a context from any thread.Yeah. Right. MPMs Suck. */
1190 te = malloc(sizeof(timer_event_t));
1191 APR_RING_ELEM_INIT(te, link);
1196 /* XXXXX: optimize */
1197 te->when = t + apr_time_now();
1199 /* Okay, insert sorted by when.. */
1200 for (ep = APR_RING_FIRST(&timer_ring);
1201 ep != APR_RING_SENTINEL(&timer_ring,
1202 timer_event_t, link);
1203 ep = APR_RING_NEXT(ep, link))
1205 if (ep->when > te->when) {
1207 APR_RING_INSERT_BEFORE(ep, te, link);
1213 APR_RING_INSERT_TAIL(&timer_ring, te, timer_event_t, link);
1216 apr_thread_mutex_unlock(g_timer_ring_mtx);
1221 static void process_lingering_close(conn_state_t *cs, const apr_pollfd_t *pfd)
1223 apr_socket_t *csd = ap_get_conn_socket(cs->c);
1224 char dummybuf[2048];
1227 struct timeout_queue *q;
1228 q = (cs->state == CONN_STATE_LINGER_SHORT) ? &short_linger_q : &linger_q;
1230 /* socket is already in non-blocking state */
1232 nbytes = sizeof(dummybuf);
1233 rv = apr_socket_recv(csd, dummybuf, &nbytes);
1234 } while (rv == APR_SUCCESS);
1236 if (!APR_STATUS_IS_EOF(rv)) {
1240 rv = apr_pollset_remove(event_pollset, pfd);
1241 AP_DEBUG_ASSERT(rv == APR_SUCCESS);
1243 rv = apr_socket_close(csd);
1244 AP_DEBUG_ASSERT(rv == APR_SUCCESS);
1246 apr_thread_mutex_lock(timeout_mutex);
1247 TO_QUEUE_REMOVE(*q, cs);
1248 apr_thread_mutex_unlock(timeout_mutex);
1249 TO_QUEUE_ELEM_INIT(cs);
1251 apr_pool_clear(cs->p);
1252 ap_push_pool(worker_queue_info, cs->p);
1255 /* call 'func' for all elements of 'q' with timeout less than 'timeout_time'.
1256 * Pre-condition: timeout_mutex must already be locked
1257 * Post-condition: timeout_mutex will be locked again
1259 static void process_timeout_queue(struct timeout_queue *q,
1260 apr_time_t timeout_time,
1261 int (*func)(conn_state_t *))
1264 conn_state_t *first, *cs, *last;
1268 AP_DEBUG_ASSERT(!APR_RING_EMPTY(&q->head, conn_state_t, timeout_list));
1270 cs = first = APR_RING_FIRST(&q->head);
1271 while (cs != APR_RING_SENTINEL(&q->head, conn_state_t, timeout_list)
1272 && cs->expiration_time < timeout_time) {
1274 cs = APR_RING_NEXT(cs, timeout_list);
1280 APR_RING_UNSPLICE(first, last, timeout_list);
1281 AP_DEBUG_ASSERT(q->count >= count);
1283 apr_thread_mutex_unlock(timeout_mutex);
1285 cs = APR_RING_NEXT(first, timeout_list);
1286 TO_QUEUE_ELEM_INIT(first);
1291 apr_thread_mutex_lock(timeout_mutex);
1294 static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy)
1299 proc_info *ti = dummy;
1300 int process_slot = ti->pid;
1301 apr_pool_t *tpool = apr_thread_pool_get(thd);
1303 apr_pool_t *ptrans; /* Pool for per-transaction stuff */
1305 int have_idle_worker = 0;
1307 const apr_pollfd_t *out_pfd;
1308 apr_int32_t num = 0;
1309 apr_interval_time_t timeout_interval;
1310 apr_time_t timeout_time = 0, now, last_log;
1311 listener_poll_type *pt;
1312 int closed = 0, listeners_disabled = 0;
1314 last_log = apr_time_now();
1317 /* the following times out events that are really close in the future
1318 * to prevent extra poll calls
1320 * current value is .1 second
1322 #define TIMEOUT_FUDGE_FACTOR 100000
1323 #define EVENT_FUDGE_FACTOR 10000
1325 rc = init_pollset(tpool);
1326 if (rc != APR_SUCCESS) {
1327 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
1328 "failed to initialize pollset, "
1329 "attempting to shutdown process gracefully");
1330 signal_threads(ST_GRACEFUL);
1334 /* Unblock the signal used to wake this thread up, and set a handler for
1337 unblock_signal(LISTENER_SIGNAL);
1338 apr_signal(LISTENER_SIGNAL, dummy_signal_handler);
1341 int workers_were_busy = 0;
1342 if (listener_may_exit) {
1343 close_listeners(process_slot, &closed);
1344 if (terminate_mode == ST_UNGRACEFUL
1345 || apr_atomic_read32(&connection_count) == 0)
1349 if (requests_this_child <= 0) {
1350 check_infinite_requests();
1353 now = apr_time_now();
1354 if (APLOGtrace6(ap_server_conf)) {
1355 /* trace log status every second */
1356 if (now - last_log > apr_time_from_msec(1000)) {
1358 apr_thread_mutex_lock(timeout_mutex);
1359 ap_log_error(APLOG_MARK, APLOG_TRACE6, 0, ap_server_conf,
1360 "connections: %d (write-completion: %d "
1361 "keep-alive: %d lingering: %d)",
1362 connection_count, write_completion_q.count,
1364 linger_q.count + short_linger_q.count);
1365 apr_thread_mutex_unlock(timeout_mutex);
1369 apr_thread_mutex_lock(g_timer_ring_mtx);
1370 if (!APR_RING_EMPTY(&timer_ring, timer_event_t, link)) {
1371 te = APR_RING_FIRST(&timer_ring);
1372 if (te->when > now) {
1373 timeout_interval = te->when - now;
1376 timeout_interval = 1;
1380 timeout_interval = apr_time_from_msec(100);
1382 apr_thread_mutex_unlock(g_timer_ring_mtx);
1385 rc = serf_context_prerun(g_serf);
1386 if (rc != APR_SUCCESS) {
1387 /* TOOD: what should do here? ugh. */
1390 rc = apr_pollset_poll(event_pollset, timeout_interval, &num, &out_pfd);
1391 if (rc != APR_SUCCESS) {
1392 if (APR_STATUS_IS_EINTR(rc)) {
1395 if (!APR_STATUS_IS_TIMEUP(rc)) {
1396 ap_log_error(APLOG_MARK, APLOG_CRIT, rc, ap_server_conf,
1397 "apr_pollset_poll failed. Attempting to "
1398 "shutdown process gracefully");
1399 signal_threads(ST_GRACEFUL);
1403 if (listener_may_exit) {
1404 close_listeners(process_slot, &closed);
1405 if (terminate_mode == ST_UNGRACEFUL
1406 || apr_atomic_read32(&connection_count) == 0)
1410 now = apr_time_now();
1411 apr_thread_mutex_lock(g_timer_ring_mtx);
1412 for (ep = APR_RING_FIRST(&timer_ring);
1413 ep != APR_RING_SENTINEL(&timer_ring,
1414 timer_event_t, link);
1415 ep = APR_RING_FIRST(&timer_ring))
1417 if (ep->when < now + EVENT_FUDGE_FACTOR) {
1418 APR_RING_REMOVE(ep, link);
1419 push_timer2worker(ep);
1425 apr_thread_mutex_unlock(g_timer_ring_mtx);
1428 pt = (listener_poll_type *) out_pfd->client_data;
1429 if (pt->type == PT_CSD) {
1430 /* one of the sockets is readable */
1431 struct timeout_queue *remove_from_q = &write_completion_q;
1433 cs = (conn_state_t *) pt->baton;
1434 switch (cs->state) {
1435 case CONN_STATE_CHECK_REQUEST_LINE_READABLE:
1436 cs->state = CONN_STATE_READ_REQUEST_LINE;
1437 remove_from_q = &keepalive_q;
1438 /* don't wait for a worker for a keepalive request */
1441 case CONN_STATE_WRITE_COMPLETION:
1442 get_worker(&have_idle_worker, blocking,
1443 &workers_were_busy);
1444 apr_thread_mutex_lock(timeout_mutex);
1445 TO_QUEUE_REMOVE(*remove_from_q, cs);
1446 apr_thread_mutex_unlock(timeout_mutex);
1447 TO_QUEUE_ELEM_INIT(cs);
1448 /* If we didn't get a worker immediately for a keep-alive
1449 * request, we close the connection, so that the client can
1450 * re-connect to a different process.
1452 if (!have_idle_worker) {
1453 start_lingering_close(cs);
1456 rc = push2worker(out_pfd, event_pollset);
1457 if (rc != APR_SUCCESS) {
1458 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1459 ap_server_conf, "push2worker failed");
1462 have_idle_worker = 0;
1465 case CONN_STATE_LINGER_NORMAL:
1466 case CONN_STATE_LINGER_SHORT:
1467 process_lingering_close(cs, out_pfd);
1470 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1472 "event_loop: unexpected state %d",
1477 else if (pt->type == PT_ACCEPT) {
1478 /* A Listener Socket is ready for an accept() */
1479 if (workers_were_busy) {
1480 if (!listeners_disabled)
1481 disable_listensocks(process_slot);
1482 listeners_disabled = 1;
1483 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1484 "All workers busy, not accepting new conns"
1487 else if (apr_atomic_read32(&connection_count) > threads_per_child
1488 + ap_queue_info_get_idlers(worker_queue_info) *
1489 worker_factor / WORKER_FACTOR_SCALE)
1491 if (!listeners_disabled)
1492 disable_listensocks(process_slot);
1493 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1494 "Too many open connections (%u), "
1495 "not accepting new conns in this process",
1496 apr_atomic_read32(&connection_count));
1497 ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
1499 ap_queue_info_get_idlers(worker_queue_info));
1500 listeners_disabled = 1;
1502 else if (listeners_disabled) {
1503 listeners_disabled = 0;
1504 enable_listensocks(process_slot);
1506 if (!listeners_disabled) {
1507 lr = (ap_listen_rec *) pt->baton;
1508 ap_pop_pool(&ptrans, worker_queue_info);
1510 if (ptrans == NULL) {
1511 /* create a new transaction pool for each accepted socket */
1512 apr_allocator_t *allocator;
1514 apr_allocator_create(&allocator);
1515 apr_allocator_max_free_set(allocator,
1517 apr_pool_create_ex(&ptrans, pconf, NULL, allocator);
1518 apr_allocator_owner_set(allocator, ptrans);
1519 if (ptrans == NULL) {
1520 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1522 "Failed to create transaction pool");
1523 signal_threads(ST_GRACEFUL);
1527 apr_pool_tag(ptrans, "transaction");
1529 get_worker(&have_idle_worker, 1, &workers_were_busy);
1530 rc = lr->accept_func(&csd, lr, ptrans);
1532 /* later we trash rv and rely on csd to indicate
1535 AP_DEBUG_ASSERT(rc == APR_SUCCESS || !csd);
1537 if (rc == APR_EGENERAL) {
1538 /* E[NM]FILE, ENOMEM, etc */
1539 resource_shortage = 1;
1540 signal_threads(ST_GRACEFUL);
1544 rc = ap_queue_push(worker_queue, csd, NULL, ptrans);
1545 if (rc != APR_SUCCESS) {
1546 /* trash the connection; we couldn't queue the connected
1547 * socket to a worker
1549 apr_socket_close(csd);
1550 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1552 "ap_queue_push failed");
1553 apr_pool_clear(ptrans);
1554 ap_push_pool(worker_queue_info, ptrans);
1557 have_idle_worker = 0;
1561 apr_pool_clear(ptrans);
1562 ap_push_pool(worker_queue_info, ptrans);
1565 } /* if:else on pt->type */
1567 else if (pt->type == PT_SERF) {
1568 /* send socket to serf. */
1569 /* XXXX: this doesn't require get_worker() */
1570 serf_event_trigger(g_serf, pt->baton, out_pfd);
1575 } /* while for processing poll */
1577 /* XXX possible optimization: stash the current time for use as
1578 * r->request_time for new requests
1580 now = apr_time_now();
1581 /* we only do this once per 0.1s (TIMEOUT_FUDGE_FACTOR) */
1582 if (now > timeout_time) {
1583 struct process_score *ps;
1584 timeout_time = now + TIMEOUT_FUDGE_FACTOR;
1586 /* handle timed out sockets */
1587 apr_thread_mutex_lock(timeout_mutex);
1589 /* Step 1: keepalive timeouts */
1590 /* If all workers are busy, we kill older keep-alive connections so that they
1591 * may connect to another process.
1593 if (workers_were_busy && keepalive_q.count) {
1594 ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
1595 "All workers are busy, will close %d keep-alive "
1598 process_timeout_queue(&keepalive_q,
1599 timeout_time + ap_server_conf->keep_alive_timeout,
1600 start_lingering_close);
1603 process_timeout_queue(&keepalive_q, timeout_time,
1604 start_lingering_close);
1606 /* Step 2: write completion timeouts */
1607 process_timeout_queue(&write_completion_q, timeout_time, start_lingering_close);
1608 /* Step 3: (normal) lingering close completion timeouts */
1609 process_timeout_queue(&linger_q, timeout_time, stop_lingering_close);
1610 /* Step 4: (short) lingering close completion timeouts */
1611 process_timeout_queue(&short_linger_q, timeout_time, stop_lingering_close);
1613 ps = ap_get_scoreboard_process(process_slot);
1614 ps->write_completion = write_completion_q.count;
1615 ps->lingering_close = linger_q.count + short_linger_q.count;
1616 ps->keep_alive = keepalive_q.count;
1617 apr_thread_mutex_unlock(timeout_mutex);
1619 ps->connections = apr_atomic_read32(&connection_count);
1620 /* XXX: should count CONN_STATE_SUSPENDED and set ps->suspended */
1622 if (listeners_disabled && !workers_were_busy &&
1623 (int)apr_atomic_read32(&connection_count) <
1624 ((int)ap_queue_info_get_idlers(worker_queue_info) - 1) *
1625 worker_factor / WORKER_FACTOR_SCALE + threads_per_child)
1627 listeners_disabled = 0;
1628 enable_listensocks(process_slot);
1631 * XXX: do we need to set some timeout that re-enables the listensocks
1632 * XXX: in case no other event occurs?
1634 } /* listener main loop */
1636 close_listeners(process_slot, &closed);
1637 ap_queue_term(worker_queue);
1639 apr_thread_exit(thd, APR_SUCCESS);
1643 /* XXX For ungraceful termination/restart, we definitely don't want to
1644 * wait for active connections to finish but we may want to wait
1645 * for idle workers to get out of the queue code and release mutexes,
1646 * since those mutexes are cleaned up pretty soon and some systems
1647 * may not react favorably (i.e., segfault) if operations are attempted
1648 * on cleaned-up mutexes.
1650 static void *APR_THREAD_FUNC worker_thread(apr_thread_t * thd, void *dummy)
1652 proc_info *ti = dummy;
1653 int process_slot = ti->pid;
1654 int thread_slot = ti->tid;
1655 apr_socket_t *csd = NULL;
1657 apr_pool_t *ptrans; /* Pool for per-transaction stuff */
1660 timer_event_t *te = NULL;
1664 ap_scoreboard_image->servers[process_slot][thread_slot].pid = ap_my_pid;
1665 ap_scoreboard_image->servers[process_slot][thread_slot].tid = apr_os_thread_current();
1666 ap_scoreboard_image->servers[process_slot][thread_slot].generation = retained->my_generation;
1667 ap_update_child_status_from_indexes(process_slot, thread_slot,
1668 SERVER_STARTING, NULL);
1670 while (!workers_may_exit) {
1672 rv = ap_queue_info_set_idle(worker_queue_info, NULL);
1673 if (rv != APR_SUCCESS) {
1674 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
1675 "ap_queue_info_set_idle failed. Attempting to "
1676 "shutdown process gracefully.");
1677 signal_threads(ST_GRACEFUL);
1683 ap_update_child_status_from_indexes(process_slot, thread_slot,
1684 dying ? SERVER_GRACEFUL : SERVER_READY, NULL);
1686 if (workers_may_exit) {
1691 rv = ap_queue_pop_something(worker_queue, &csd, &cs, &ptrans, &te);
1693 if (rv != APR_SUCCESS) {
1694 /* We get APR_EOF during a graceful shutdown once all the
1695 * connections accepted by this server process have been handled.
1697 if (APR_STATUS_IS_EOF(rv)) {
1700 /* We get APR_EINTR whenever ap_queue_pop() has been interrupted
1701 * from an explicit call to ap_queue_interrupt_all(). This allows
1702 * us to unblock threads stuck in ap_queue_pop() when a shutdown
1705 * If workers_may_exit is set and this is ungraceful termination/
1706 * restart, we are bound to get an error on some systems (e.g.,
1707 * AIX, which sanity-checks mutex operations) since the queue
1708 * may have already been cleaned up. Don't log the "error" if
1709 * workers_may_exit is set.
1711 else if (APR_STATUS_IS_EINTR(rv)) {
1714 /* We got some other error. */
1715 else if (!workers_may_exit) {
1716 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1717 "ap_queue_pop failed");
1722 te->cbfunc(te->baton);
1725 apr_thread_mutex_lock(g_timer_ring_mtx);
1726 APR_RING_INSERT_TAIL(&timer_free_ring, te, timer_event_t, link);
1727 apr_thread_mutex_unlock(g_timer_ring_mtx);
1732 worker_sockets[thread_slot] = csd;
1733 rv = process_socket(thd, ptrans, csd, cs, process_slot, thread_slot);
1735 requests_this_child--;
1737 worker_sockets[thread_slot] = NULL;
1741 ap_update_child_status_from_indexes(process_slot, thread_slot,
1742 dying ? SERVER_DEAD :
1744 (request_rec *) NULL);
1746 apr_thread_exit(thd, APR_SUCCESS);
1750 static int check_signal(int signum)
1762 static void create_listener_thread(thread_starter * ts)
1764 int my_child_num = ts->child_num_arg;
1765 apr_threadattr_t *thread_attr = ts->threadattr;
1769 my_info = (proc_info *) malloc(sizeof(proc_info));
1770 my_info->pid = my_child_num;
1771 my_info->tid = -1; /* listener thread doesn't have a thread slot */
1773 rv = apr_thread_create(&ts->listener, thread_attr, listener_thread,
1775 if (rv != APR_SUCCESS) {
1776 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1777 "apr_thread_create: unable to create listener thread");
1778 /* let the parent decide how bad this really is */
1779 clean_child_exit(APEXIT_CHILDSICK);
1781 apr_os_thread_get(&listener_os_thread, ts->listener);
1784 /* XXX under some circumstances not understood, children can get stuck
1785 * in start_threads forever trying to take over slots which will
1786 * never be cleaned up; for now there is an APLOG_DEBUG message issued
1787 * every so often when this condition occurs
1789 static void *APR_THREAD_FUNC start_threads(apr_thread_t * thd, void *dummy)
1791 thread_starter *ts = dummy;
1792 apr_thread_t **threads = ts->threads;
1793 apr_threadattr_t *thread_attr = ts->threadattr;
1794 int child_num_arg = ts->child_num_arg;
1795 int my_child_num = child_num_arg;
1799 int threads_created = 0;
1800 int listener_started = 0;
1802 int prev_threads_created;
1803 int max_recycled_pools = -1;
1805 /* We must create the fd queues before we start up the listener
1806 * and worker threads. */
1807 worker_queue = apr_pcalloc(pchild, sizeof(*worker_queue));
1808 rv = ap_queue_init(worker_queue, threads_per_child, pchild);
1809 if (rv != APR_SUCCESS) {
1810 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1811 "ap_queue_init() failed");
1812 clean_child_exit(APEXIT_CHILDFATAL);
1815 if (ap_max_mem_free != APR_ALLOCATOR_MAX_FREE_UNLIMITED) {
1816 /* If we want to conserve memory, let's not keep an unlimited number of
1817 * pools & allocators.
1818 * XXX: This should probably be a separate config directive
1820 max_recycled_pools = threads_per_child * 3 / 4 ;
1822 rv = ap_queue_info_create(&worker_queue_info, pchild,
1823 threads_per_child, max_recycled_pools);
1824 if (rv != APR_SUCCESS) {
1825 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1826 "ap_queue_info_create() failed");
1827 clean_child_exit(APEXIT_CHILDFATAL);
1830 /* Create the timeout mutex and main pollset before the listener
1833 rv = apr_thread_mutex_create(&timeout_mutex, APR_THREAD_MUTEX_DEFAULT,
1835 if (rv != APR_SUCCESS) {
1836 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
1837 "creation of the timeout mutex failed.");
1838 clean_child_exit(APEXIT_CHILDFATAL);
1841 /* Create the main pollset */
1842 rv = apr_pollset_create(&event_pollset,
1843 threads_per_child, /* XXX don't we need more, to handle
1844 * connections in K-A or lingering
1847 pchild, APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY);
1848 if (rv != APR_SUCCESS) {
1849 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
1850 "apr_pollset_create with Thread Safety failed.");
1851 clean_child_exit(APEXIT_CHILDFATAL);
1854 worker_sockets = apr_pcalloc(pchild, threads_per_child
1855 * sizeof(apr_socket_t *));
1857 loops = prev_threads_created = 0;
1859 /* threads_per_child does not include the listener thread */
1860 for (i = 0; i < threads_per_child; i++) {
1862 ap_scoreboard_image->servers[child_num_arg][i].status;
1864 if (status != SERVER_GRACEFUL && status != SERVER_DEAD) {
1868 my_info = (proc_info *) malloc(sizeof(proc_info));
1869 if (my_info == NULL) {
1870 ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf,
1871 "malloc: out of memory");
1872 clean_child_exit(APEXIT_CHILDFATAL);
1874 my_info->pid = my_child_num;
1878 /* We are creating threads right now */
1879 ap_update_child_status_from_indexes(my_child_num, i,
1880 SERVER_STARTING, NULL);
1881 /* We let each thread update its own scoreboard entry. This is
1882 * done because it lets us deal with tid better.
1884 rv = apr_thread_create(&threads[i], thread_attr,
1885 worker_thread, my_info, pchild);
1886 if (rv != APR_SUCCESS) {
1887 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1888 "apr_thread_create: unable to create worker thread");
1889 /* let the parent decide how bad this really is */
1890 clean_child_exit(APEXIT_CHILDSICK);
1895 /* Start the listener only when there are workers available */
1896 if (!listener_started && threads_created) {
1897 create_listener_thread(ts);
1898 listener_started = 1;
1902 if (start_thread_may_exit || threads_created == threads_per_child) {
1905 /* wait for previous generation to clean up an entry */
1906 apr_sleep(apr_time_from_sec(1));
1908 if (loops % 120 == 0) { /* every couple of minutes */
1909 if (prev_threads_created == threads_created) {
1910 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1911 "child %" APR_PID_T_FMT " isn't taking over "
1912 "slots very quickly (%d of %d)",
1913 ap_my_pid, threads_created,
1916 prev_threads_created = threads_created;
1920 /* What state should this child_main process be listed as in the
1922 * ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING,
1923 * (request_rec *) NULL);
1925 * This state should be listed separately in the scoreboard, in some kind
1926 * of process_status, not mixed in with the worker threads' status.
1927 * "life_status" is almost right, but it's in the worker's structure, and
1928 * the name could be clearer. gla
1930 apr_thread_exit(thd, APR_SUCCESS);
1934 static void join_workers(apr_thread_t * listener, apr_thread_t ** threads)
1937 apr_status_t rv, thread_rv;
1942 /* deal with a rare timing window which affects waking up the
1943 * listener thread... if the signal sent to the listener thread
1944 * is delivered between the time it verifies that the
1945 * listener_may_exit flag is clear and the time it enters a
1946 * blocking syscall, the signal didn't do any good... work around
1947 * that by sleeping briefly and sending it again
1951 while (iter < 10 && !dying) {
1952 /* listener has not stopped accepting yet */
1953 apr_sleep(apr_time_make(0, 500000));
1958 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1959 "the listener thread didn't stop accepting");
1962 rv = apr_thread_join(&thread_rv, listener);
1963 if (rv != APR_SUCCESS) {
1964 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1965 "apr_thread_join: unable to join listener thread");
1970 for (i = 0; i < threads_per_child; i++) {
1971 if (threads[i]) { /* if we ever created this thread */
1972 rv = apr_thread_join(&thread_rv, threads[i]);
1973 if (rv != APR_SUCCESS) {
1974 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1975 "apr_thread_join: unable to join worker "
1982 static void join_start_thread(apr_thread_t * start_thread_id)
1984 apr_status_t rv, thread_rv;
1986 start_thread_may_exit = 1; /* tell it to give up in case it is still
1987 * trying to take over slots from a
1988 * previous generation
1990 rv = apr_thread_join(&thread_rv, start_thread_id);
1991 if (rv != APR_SUCCESS) {
1992 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1993 "apr_thread_join: unable to join the start " "thread");
1997 static void child_main(int child_num_arg)
1999 apr_thread_t **threads;
2002 apr_threadattr_t *thread_attr;
2003 apr_thread_t *start_thread_id;
2005 mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
2008 ap_my_pid = getpid();
2009 ap_fatal_signal_child_setup(ap_server_conf);
2010 apr_pool_create(&pchild, pconf);
2012 /*stuff to do before we switch id's, so we have permissions. */
2013 ap_reopen_scoreboard(pchild, NULL, 0);
2015 if (ap_run_drop_privileges(pchild, ap_server_conf)) {
2016 clean_child_exit(APEXIT_CHILDFATAL);
2019 apr_thread_mutex_create(&g_timer_ring_mtx, APR_THREAD_MUTEX_DEFAULT, pchild);
2020 APR_RING_INIT(&timer_free_ring, timer_event_t, link);
2021 APR_RING_INIT(&timer_ring, timer_event_t, link);
2022 ap_run_child_init(pchild, ap_server_conf);
2024 /* done with init critical section */
2026 /* Just use the standard apr_setup_signal_thread to block all signals
2027 * from being received. The child processes no longer use signals for
2028 * any communication with the parent process.
2030 rv = apr_setup_signal_thread();
2031 if (rv != APR_SUCCESS) {
2032 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
2033 "Couldn't initialize signal thread");
2034 clean_child_exit(APEXIT_CHILDFATAL);
2037 if (ap_max_requests_per_child) {
2038 requests_this_child = ap_max_requests_per_child;
2041 /* coding a value of zero means infinity */
2042 requests_this_child = INT_MAX;
2045 /* Setup worker threads */
2047 /* clear the storage; we may not create all our threads immediately,
2048 * and we want a 0 entry to indicate a thread which was not created
2050 threads = (apr_thread_t **) calloc(1,
2051 sizeof(apr_thread_t *) *
2053 if (threads == NULL) {
2054 ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf,
2055 "malloc: out of memory");
2056 clean_child_exit(APEXIT_CHILDFATAL);
2059 ts = (thread_starter *) apr_palloc(pchild, sizeof(*ts));
2061 apr_threadattr_create(&thread_attr, pchild);
2062 /* 0 means PTHREAD_CREATE_JOINABLE */
2063 apr_threadattr_detach_set(thread_attr, 0);
2065 if (ap_thread_stacksize != 0) {
2066 apr_threadattr_stacksize_set(thread_attr, ap_thread_stacksize);
2069 ts->threads = threads;
2070 ts->listener = NULL;
2071 ts->child_num_arg = child_num_arg;
2072 ts->threadattr = thread_attr;
2074 rv = apr_thread_create(&start_thread_id, thread_attr, start_threads,
2076 if (rv != APR_SUCCESS) {
2077 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
2078 "apr_thread_create: unable to create worker thread");
2079 /* let the parent decide how bad this really is */
2080 clean_child_exit(APEXIT_CHILDSICK);
2083 mpm_state = AP_MPMQ_RUNNING;
2085 /* If we are only running in one_process mode, we will want to
2086 * still handle signals. */
2088 /* Block until we get a terminating signal. */
2089 apr_signal_thread(check_signal);
2090 /* make sure the start thread has finished; signal_threads()
2091 * and join_workers() depend on that
2093 /* XXX join_start_thread() won't be awakened if one of our
2094 * threads encounters a critical error and attempts to
2095 * shutdown this child
2097 join_start_thread(start_thread_id);
2099 /* helps us terminate a little more quickly than the dispatch of the
2100 * signal thread; beats the Pipe of Death and the browsers
2102 signal_threads(ST_UNGRACEFUL);
2104 /* A terminating signal was received. Now join each of the
2105 * workers to clean them up.
2106 * If the worker already exited, then the join frees
2107 * their resources and returns.
2108 * If the worker hasn't exited, then this blocks until
2109 * they have (then cleans up).
2111 join_workers(ts->listener, threads);
2113 else { /* !one_process */
2114 /* remove SIGTERM from the set of blocked signals... if one of
2115 * the other threads in the process needs to take us down
2116 * (e.g., for MaxConnectionsPerChild) it will send us SIGTERM
2118 unblock_signal(SIGTERM);
2119 apr_signal(SIGTERM, dummy_signal_handler);
2120 /* Watch for any messages from the parent over the POD */
2122 rv = ap_event_pod_check(pod);
2123 if (rv == AP_NORESTART) {
2124 /* see if termination was triggered while we slept */
2125 switch (terminate_mode) {
2134 if (rv == AP_GRACEFUL || rv == AP_RESTART) {
2135 /* make sure the start thread has finished;
2136 * signal_threads() and join_workers depend on that
2138 join_start_thread(start_thread_id);
2139 signal_threads(rv ==
2140 AP_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL);
2145 /* A terminating signal was received. Now join each of the
2146 * workers to clean them up.
2147 * If the worker already exited, then the join frees
2148 * their resources and returns.
2149 * If the worker hasn't exited, then this blocks until
2150 * they have (then cleans up).
2152 join_workers(ts->listener, threads);
2157 clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0);
2160 static int make_child(server_rec * s, int slot)
2164 if (slot + 1 > retained->max_daemons_limit) {
2165 retained->max_daemons_limit = slot + 1;
2170 event_note_child_started(slot, getpid());
2175 if ((pid = fork()) == -1) {
2176 ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
2177 "fork: Unable to fork new process");
2179 /* fork didn't succeed. There's no need to touch the scoreboard;
2180 * if we were trying to replace a failed child process, then
2181 * server_main_loop() marked its workers SERVER_DEAD, and if
2182 * we were trying to replace a child process that exited normally,
2183 * its worker_thread()s left SERVER_DEAD or SERVER_GRACEFUL behind.
2186 /* In case system resources are maxxed out, we don't want
2187 Apache running away with the CPU trying to fork over and
2188 over and over again. */
2189 apr_sleep(apr_time_from_sec(10));
2195 #ifdef HAVE_BINDPROCESSOR
2196 /* By default, AIX binds to a single processor. This bit unbinds
2197 * children which will then bind to another CPU.
2199 int status = bindprocessor(BINDPROCESS, (int) getpid(),
2200 PROCESSOR_CLASS_ANY);
2202 ap_log_error(APLOG_MARK, APLOG_DEBUG, errno,
2204 "processor unbind failed");
2206 RAISE_SIGSTOP(MAKE_CHILD);
2208 apr_signal(SIGTERM, just_die);
2213 if (ap_scoreboard_image->parent[slot].pid != 0) {
2214 /* This new child process is squatting on the scoreboard
2215 * entry owned by an exiting child process, which cannot
2216 * exit until all active requests complete.
2218 event_note_child_lost_slot(slot, pid);
2220 ap_scoreboard_image->parent[slot].quiescing = 0;
2221 ap_scoreboard_image->parent[slot].not_accepting = 0;
2222 event_note_child_started(slot, pid);
2226 /* start up a bunch of children */
2227 static void startup_children(int number_to_start)
2231 for (i = 0; number_to_start && i < ap_daemons_limit; ++i) {
2232 if (ap_scoreboard_image->parent[i].pid != 0) {
2235 if (make_child(ap_server_conf, i) < 0) {
2242 static void perform_idle_server_maintenance(void)
2245 int idle_thread_count;
2249 int totally_free_length = 0;
2250 int free_slots[MAX_SPAWN_RATE];
2253 int active_thread_count = 0;
2255 /* initialize the free_list */
2258 idle_thread_count = 0;
2262 for (i = 0; i < ap_daemons_limit; ++i) {
2263 /* Initialization to satisfy the compiler. It doesn't know
2264 * that threads_per_child is always > 0 */
2265 int status = SERVER_DEAD;
2266 int any_dying_threads = 0;
2267 int any_dead_threads = 0;
2268 int all_dead_threads = 1;
2270 if (i >= retained->max_daemons_limit
2271 && totally_free_length == retained->idle_spawn_rate)
2272 /* short cut if all active processes have been examined and
2273 * enough empty scoreboard slots have been found
2277 ps = &ap_scoreboard_image->parent[i];
2278 for (j = 0; j < threads_per_child; j++) {
2279 ws = &ap_scoreboard_image->servers[i][j];
2280 status = ws->status;
2282 /* XXX any_dying_threads is probably no longer needed GLA */
2283 any_dying_threads = any_dying_threads ||
2284 (status == SERVER_GRACEFUL);
2285 any_dead_threads = any_dead_threads || (status == SERVER_DEAD);
2286 all_dead_threads = all_dead_threads &&
2287 (status == SERVER_DEAD || status == SERVER_GRACEFUL);
2289 /* We consider a starting server as idle because we started it
2290 * at least a cycle ago, and if it still hasn't finished starting
2291 * then we're just going to swamp things worse by forking more.
2292 * So we hopefully won't need to fork more if we count it.
2293 * This depends on the ordering of SERVER_READY and SERVER_STARTING.
2295 if (ps->pid != 0) { /* XXX just set all_dead_threads in outer
2296 for loop if no pid? not much else matters */
2297 if (status <= SERVER_READY && !ps->quiescing && !ps->not_accepting
2298 && ps->generation == retained->my_generation)
2300 ++idle_thread_count;
2302 if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
2303 ++active_thread_count;
2307 if (any_dead_threads
2308 && totally_free_length < retained->idle_spawn_rate
2309 && free_length < MAX_SPAWN_RATE
2310 && (!ps->pid /* no process in the slot */
2311 || ps->quiescing)) { /* or at least one is going away */
2312 if (all_dead_threads) {
2313 /* great! we prefer these, because the new process can
2314 * start more threads sooner. So prioritize this slot
2315 * by putting it ahead of any slots with active threads.
2317 * first, make room by moving a slot that's potentially still
2318 * in use to the end of the array
2320 free_slots[free_length] = free_slots[totally_free_length];
2321 free_slots[totally_free_length++] = i;
2324 /* slot is still in use - back of the bus
2326 free_slots[free_length] = i;
2330 /* XXX if (!ps->quiescing) is probably more reliable GLA */
2331 if (!any_dying_threads) {
2337 if (retained->sick_child_detected) {
2338 if (active_thread_count > 0) {
2339 /* some child processes appear to be working. don't kill the
2342 retained->sick_child_detected = 0;
2345 /* looks like a basket case. give up.
2347 shutdown_pending = 1;
2349 ap_log_error(APLOG_MARK, APLOG_ALERT, 0,
2351 "No active workers found..."
2352 " Apache is exiting!");
2353 /* the child already logged the failure details */
2358 retained->max_daemons_limit = last_non_dead + 1;
2360 if (idle_thread_count > max_spare_threads) {
2361 /* Kill off one child */
2362 ap_event_pod_signal(pod, TRUE);
2363 retained->idle_spawn_rate = 1;
2365 else if (idle_thread_count < min_spare_threads) {
2366 /* terminate the free list */
2367 if (free_length == 0) { /* scoreboard is full, can't fork */
2369 if (active_thread_count >= ap_daemons_limit * threads_per_child) {
2370 if (!retained->maxclients_reported) {
2371 /* only report this condition once */
2372 ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
2373 "server reached MaxRequestWorkers setting, "
2374 "consider raising the MaxRequestWorkers "
2376 retained->maxclients_reported = 1;
2380 ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
2381 "scoreboard is full, not at MaxRequestWorkers");
2383 retained->idle_spawn_rate = 1;
2386 if (free_length > retained->idle_spawn_rate) {
2387 free_length = retained->idle_spawn_rate;
2389 if (retained->idle_spawn_rate >= 8) {
2390 ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
2391 "server seems busy, (you may need "
2392 "to increase StartServers, ThreadsPerChild "
2393 "or Min/MaxSpareThreads), "
2394 "spawning %d children, there are around %d idle "
2395 "threads, and %d total children", free_length,
2396 idle_thread_count, total_non_dead);
2398 for (i = 0; i < free_length; ++i) {
2399 make_child(ap_server_conf, free_slots[i]);
2401 /* the next time around we want to spawn twice as many if this
2402 * wasn't good enough, but not if we've just done a graceful
2404 if (retained->hold_off_on_exponential_spawning) {
2405 --retained->hold_off_on_exponential_spawning;
2407 else if (retained->idle_spawn_rate < MAX_SPAWN_RATE) {
2408 retained->idle_spawn_rate *= 2;
2413 retained->idle_spawn_rate = 1;
2417 static void server_main_loop(int remaining_children_to_start)
2419 ap_generation_t old_gen;
2421 apr_exit_why_e exitwhy;
2422 int status, processed_status;
2426 while (!restart_pending && !shutdown_pending) {
2427 ap_wait_or_timeout(&exitwhy, &status, &pid, pconf, ap_server_conf);
2429 if (pid.pid != -1) {
2430 processed_status = ap_process_child_status(&pid, exitwhy, status);
2431 if (processed_status == APEXIT_CHILDFATAL) {
2432 shutdown_pending = 1;
2436 else if (processed_status == APEXIT_CHILDSICK) {
2437 /* tell perform_idle_server_maintenance to check into this
2438 * on the next timer pop
2440 retained->sick_child_detected = 1;
2442 /* non-fatal death... note that it's gone in the scoreboard. */
2443 child_slot = ap_find_child_by_pid(&pid);
2444 if (child_slot >= 0) {
2445 for (i = 0; i < threads_per_child; i++)
2446 ap_update_child_status_from_indexes(child_slot, i,
2448 (request_rec *) NULL);
2450 event_note_child_killed(child_slot, 0, 0);
2451 ap_scoreboard_image->parent[child_slot].quiescing = 0;
2452 if (processed_status == APEXIT_CHILDSICK) {
2453 /* resource shortage, minimize the fork rate */
2454 retained->idle_spawn_rate = 1;
2456 else if (remaining_children_to_start
2457 && child_slot < ap_daemons_limit) {
2458 /* we're still doing a 1-for-1 replacement of dead
2459 * children with new children
2461 make_child(ap_server_conf, child_slot);
2462 --remaining_children_to_start;
2465 else if (ap_unregister_extra_mpm_process(pid.pid, &old_gen) == 1) {
2467 event_note_child_killed(-1, /* already out of the scoreboard */
2469 #if APR_HAS_OTHER_CHILD
2471 else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH,
2476 else if (retained->is_graceful) {
2477 /* Great, we've probably just lost a slot in the
2478 * scoreboard. Somehow we don't know about this child.
2480 ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
2482 "long lost child came home! (pid %ld)",
2485 /* Don't perform idle maintenance when a child dies,
2486 * only do it when there's a timeout. Remember only a
2487 * finite number of children can die, and it's pretty
2488 * pathological for a lot to die suddenly.
2492 else if (remaining_children_to_start) {
2493 /* we hit a 1 second timeout in which none of the previous
2494 * generation of children needed to be reaped... so assume
2495 * they're all done, and pick up the slack if any is left.
2497 startup_children(remaining_children_to_start);
2498 remaining_children_to_start = 0;
2499 /* In any event we really shouldn't do the code below because
2500 * few of the servers we just started are in the IDLE state
2501 * yet, so we'd mistakenly create an extra server.
2506 perform_idle_server_maintenance();
2510 static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
2512 int remaining_children_to_start;
2514 ap_log_pid(pconf, ap_pid_fname);
2516 if (!retained->is_graceful) {
2517 if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
2518 mpm_state = AP_MPMQ_STOPPING;
2521 /* fix the generation number in the global score; we just got a new,
2522 * cleared scoreboard
2524 ap_scoreboard_image->global->running_generation = retained->my_generation;
2528 /* Don't thrash... */
2529 if (max_spare_threads < min_spare_threads + threads_per_child)
2530 max_spare_threads = min_spare_threads + threads_per_child;
2532 /* If we're doing a graceful_restart then we're going to see a lot
2533 * of children exiting immediately when we get into the main loop
2534 * below (because we just sent them AP_SIG_GRACEFUL). This happens pretty
2535 * rapidly... and for each one that exits we may start a new one, until
2536 * there are at least min_spare_threads idle threads, counting across
2537 * all children. But we may be permitted to start more children than
2538 * that, so we'll just keep track of how many we're
2539 * supposed to start up without the 1 second penalty between each fork.
2541 remaining_children_to_start = ap_daemons_to_start;
2542 if (remaining_children_to_start > ap_daemons_limit) {
2543 remaining_children_to_start = ap_daemons_limit;
2545 if (!retained->is_graceful) {
2546 startup_children(remaining_children_to_start);
2547 remaining_children_to_start = 0;
2550 /* give the system some time to recover before kicking into
2551 * exponential mode */
2552 retained->hold_off_on_exponential_spawning = 10;
2555 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2556 "%s configured -- resuming normal operations",
2557 ap_get_server_description());
2558 ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
2559 "Server built: %s", ap_get_server_built());
2560 ap_log_command_line(plog, s);
2562 restart_pending = shutdown_pending = 0;
2563 mpm_state = AP_MPMQ_RUNNING;
2565 server_main_loop(remaining_children_to_start);
2566 mpm_state = AP_MPMQ_STOPPING;
2568 if (shutdown_pending && !retained->is_graceful) {
2569 /* Time to shut down:
2570 * Kill child processes, tell them to call child_exit, etc...
2572 ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
2573 ap_reclaim_child_processes(1, /* Start with SIGTERM */
2574 event_note_child_killed);
2577 /* cleanup pid file on normal shutdown */
2578 ap_remove_pid(pconf, ap_pid_fname);
2579 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,
2580 ap_server_conf, "caught SIGTERM, shutting down");
2583 } else if (shutdown_pending) {
2584 /* Time to gracefully shut down:
2585 * Kill child processes, tell them to call child_exit, etc...
2587 int active_children;
2589 apr_time_t cutoff = 0;
2591 /* Close our listeners, and then ask our children to do same */
2592 ap_close_listeners();
2593 ap_event_pod_killpg(pod, ap_daemons_limit, TRUE);
2594 ap_relieve_child_processes(event_note_child_killed);
2597 /* cleanup pid file on normal shutdown */
2598 ap_remove_pid(pconf, ap_pid_fname);
2599 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2600 "caught " AP_SIG_GRACEFUL_STOP_STRING
2601 ", shutting down gracefully");
2604 if (ap_graceful_shutdown_timeout) {
2605 cutoff = apr_time_now() +
2606 apr_time_from_sec(ap_graceful_shutdown_timeout);
2609 /* Don't really exit until each child has finished */
2610 shutdown_pending = 0;
2612 /* Pause for a second */
2613 apr_sleep(apr_time_from_sec(1));
2615 /* Relieve any children which have now exited */
2616 ap_relieve_child_processes(event_note_child_killed);
2618 active_children = 0;
2619 for (index = 0; index < ap_daemons_limit; ++index) {
2620 if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == APR_SUCCESS) {
2621 active_children = 1;
2622 /* Having just one child is enough to stay around */
2626 } while (!shutdown_pending && active_children &&
2627 (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
2629 /* We might be here because we received SIGTERM, either
2630 * way, try and make sure that all of our processes are
2633 ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
2634 ap_reclaim_child_processes(1, event_note_child_killed);
2639 /* we've been told to restart */
2640 apr_signal(SIGHUP, SIG_IGN);
2643 /* not worth thinking about */
2647 /* advance to the next generation */
2648 /* XXX: we really need to make sure this new generation number isn't in
2649 * use by any of the children.
2651 ++retained->my_generation;
2652 ap_scoreboard_image->global->running_generation = retained->my_generation;
2654 if (retained->is_graceful) {
2655 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2656 AP_SIG_GRACEFUL_STRING
2657 " received. Doing graceful restart");
2658 /* wake up the children...time to die. But we'll have more soon */
2659 ap_event_pod_killpg(pod, ap_daemons_limit, TRUE);
2662 /* This is mostly for debugging... so that we know what is still
2663 * gracefully dealing with existing request.
2668 /* Kill 'em all. Since the child acts the same on the parents SIGTERM
2669 * and a SIGHUP, we may as well use the same signal, because some user
2670 * pthreads are stealing signals from us left and right.
2672 ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
2674 ap_reclaim_child_processes(1, /* Start with SIGTERM */
2675 event_note_child_killed);
2676 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2677 "SIGHUP received. Attempting to restart");
2683 /* This really should be a post_config hook, but the error log is already
2684 * redirected by that point, so we need to do this in the open_logs phase.
2686 static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
2687 apr_pool_t * ptemp, server_rec * s)
2690 int level_flags = 0;
2695 /* the reverse of pre_config, we want this only the first time around */
2696 if (retained->module_loads == 1) {
2698 level_flags |= APLOG_STARTUP;
2701 if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {
2702 ap_log_error(APLOG_MARK, APLOG_ALERT | level_flags, 0,
2703 (startup ? NULL : s),
2704 "no listening sockets available, shutting down");
2709 if ((rv = ap_event_pod_open(pconf, &pod))) {
2710 ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
2711 (startup ? NULL : s),
2712 "could not open pipe-of-death");
2719 static int event_pre_config(apr_pool_t * pconf, apr_pool_t * plog,
2722 int no_detach, debug, foreground;
2724 const char *userdata_key = "mpm_event_module";
2726 mpm_state = AP_MPMQ_STARTING;
2728 debug = ap_exists_config_define("DEBUG");
2731 foreground = one_process = 1;
2735 one_process = ap_exists_config_define("ONE_PROCESS");
2736 no_detach = ap_exists_config_define("NO_DETACH");
2737 foreground = ap_exists_config_define("FOREGROUND");
2740 /* sigh, want this only the second time around */
2741 retained = ap_retained_data_get(userdata_key);
2743 retained = ap_retained_data_create(userdata_key, sizeof(*retained));
2744 retained->max_daemons_limit = -1;
2745 retained->idle_spawn_rate = 1;
2747 ++retained->module_loads;
2748 if (retained->module_loads == 2) {
2749 rv = apr_pollset_create(&event_pollset, 1, plog,
2750 APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY);
2751 if (rv != APR_SUCCESS) {
2752 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,
2753 "Couldn't create a Thread Safe Pollset. "
2754 "Is it supported on your platform?"
2755 "Also check system or user limits!");
2756 return HTTP_INTERNAL_SERVER_ERROR;
2758 apr_pollset_destroy(event_pollset);
2760 if (!one_process && !foreground) {
2761 rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND
2762 : APR_PROC_DETACH_DAEMONIZE);
2763 if (rv != APR_SUCCESS) {
2764 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,
2765 "apr_proc_detach failed");
2766 return HTTP_INTERNAL_SERVER_ERROR;
2771 parent_pid = ap_my_pid = getpid();
2773 ap_listen_pre_config();
2774 ap_daemons_to_start = DEFAULT_START_DAEMON;
2775 min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
2776 max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
2777 server_limit = DEFAULT_SERVER_LIMIT;
2778 thread_limit = DEFAULT_THREAD_LIMIT;
2779 ap_daemons_limit = server_limit;
2780 threads_per_child = DEFAULT_THREADS_PER_CHILD;
2781 max_workers = ap_daemons_limit * threads_per_child;
2782 ap_extended_status = 0;
2787 static int event_check_config(apr_pool_t *p, apr_pool_t *plog,
2788 apr_pool_t *ptemp, server_rec *s)
2792 /* the reverse of pre_config, we want this only the first time around */
2793 if (retained->module_loads == 1) {
2797 if (server_limit > MAX_SERVER_LIMIT) {
2799 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2800 "WARNING: ServerLimit of %d exceeds compile-time "
2801 "limit of", server_limit);
2802 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2803 " %d servers, decreasing to %d.",
2804 MAX_SERVER_LIMIT, MAX_SERVER_LIMIT);
2806 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2807 "ServerLimit of %d exceeds compile-time limit "
2808 "of %d, decreasing to match",
2809 server_limit, MAX_SERVER_LIMIT);
2811 server_limit = MAX_SERVER_LIMIT;
2813 else if (server_limit < 1) {
2815 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2816 "WARNING: ServerLimit of %d not allowed, "
2817 "increasing to 1.", server_limit);
2819 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2820 "ServerLimit of %d not allowed, increasing to 1",
2826 /* you cannot change ServerLimit across a restart; ignore
2829 if (!retained->first_server_limit) {
2830 retained->first_server_limit = server_limit;
2832 else if (server_limit != retained->first_server_limit) {
2833 /* don't need a startup console version here */
2834 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2835 "changing ServerLimit to %d from original value of %d "
2836 "not allowed during restart",
2837 server_limit, retained->first_server_limit);
2838 server_limit = retained->first_server_limit;
2841 if (thread_limit > MAX_THREAD_LIMIT) {
2843 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2844 "WARNING: ThreadLimit of %d exceeds compile-time "
2845 "limit of", thread_limit);
2846 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2847 " %d threads, decreasing to %d.",
2848 MAX_THREAD_LIMIT, MAX_THREAD_LIMIT);
2850 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2851 "ThreadLimit of %d exceeds compile-time limit "
2852 "of %d, decreasing to match",
2853 thread_limit, MAX_THREAD_LIMIT);
2855 thread_limit = MAX_THREAD_LIMIT;
2857 else if (thread_limit < 1) {
2859 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2860 "WARNING: ThreadLimit of %d not allowed, "
2861 "increasing to 1.", thread_limit);
2863 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2864 "ThreadLimit of %d not allowed, increasing to 1",
2870 /* you cannot change ThreadLimit across a restart; ignore
2873 if (!retained->first_thread_limit) {
2874 retained->first_thread_limit = thread_limit;
2876 else if (thread_limit != retained->first_thread_limit) {
2877 /* don't need a startup console version here */
2878 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2879 "changing ThreadLimit to %d from original value of %d "
2880 "not allowed during restart",
2881 thread_limit, retained->first_thread_limit);
2882 thread_limit = retained->first_thread_limit;
2885 if (threads_per_child > thread_limit) {
2887 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2888 "WARNING: ThreadsPerChild of %d exceeds ThreadLimit "
2889 "of", threads_per_child);
2890 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2891 " %d threads, decreasing to %d.",
2892 thread_limit, thread_limit);
2893 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2894 " To increase, please see the ThreadLimit "
2897 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2898 "ThreadsPerChild of %d exceeds ThreadLimit "
2899 "of %d, decreasing to match",
2900 threads_per_child, thread_limit);
2902 threads_per_child = thread_limit;
2904 else if (threads_per_child < 1) {
2906 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2907 "WARNING: ThreadsPerChild of %d not allowed, "
2908 "increasing to 1.", threads_per_child);
2910 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2911 "ThreadsPerChild of %d not allowed, increasing to 1",
2914 threads_per_child = 1;
2917 if (max_workers < threads_per_child) {
2919 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2920 "WARNING: MaxRequestWorkers of %d is less than "
2921 "ThreadsPerChild of", max_workers);
2922 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2923 " %d, increasing to %d. MaxRequestWorkers must be at "
2925 threads_per_child, threads_per_child);
2926 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2927 " as the number of threads in a single server.");
2929 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2930 "MaxRequestWorkers of %d is less than ThreadsPerChild "
2931 "of %d, increasing to match",
2932 max_workers, threads_per_child);
2934 max_workers = threads_per_child;
2937 ap_daemons_limit = max_workers / threads_per_child;
2939 if (max_workers % threads_per_child) {
2940 int tmp_max_workers = ap_daemons_limit * threads_per_child;
2943 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2944 "WARNING: MaxRequestWorkers of %d is not an integer "
2945 "multiple of", max_workers);
2946 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2947 " ThreadsPerChild of %d, decreasing to nearest "
2948 "multiple %d,", threads_per_child,
2950 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2951 " for a maximum of %d servers.",
2954 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2955 "MaxRequestWorkers of %d is not an integer multiple "
2956 "of ThreadsPerChild of %d, decreasing to nearest "
2957 "multiple %d", max_workers, threads_per_child,
2960 max_workers = tmp_max_workers;
2963 if (ap_daemons_limit > server_limit) {
2965 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2966 "WARNING: MaxRequestWorkers of %d would require %d "
2967 "servers and ", max_workers, ap_daemons_limit);
2968 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2969 " would exceed ServerLimit of %d, decreasing to %d.",
2970 server_limit, server_limit * threads_per_child);
2971 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2972 " To increase, please see the ServerLimit "
2975 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2976 "MaxRequestWorkers of %d would require %d servers and "
2977 "exceed ServerLimit of %d, decreasing to %d",
2978 max_workers, ap_daemons_limit, server_limit,
2979 server_limit * threads_per_child);
2981 ap_daemons_limit = server_limit;
2984 /* ap_daemons_to_start > ap_daemons_limit checked in ap_mpm_run() */
2985 if (ap_daemons_to_start < 0) {
2987 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2988 "WARNING: StartServers of %d not allowed, "
2989 "increasing to 1.", ap_daemons_to_start);
2991 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2992 "StartServers of %d not allowed, increasing to 1",
2993 ap_daemons_to_start);
2995 ap_daemons_to_start = 1;
2998 if (min_spare_threads < 1) {
3000 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3001 "WARNING: MinSpareThreads of %d not allowed, "
3002 "increasing to 1", min_spare_threads);
3003 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3004 " to avoid almost certain server failure.");
3005 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3006 " Please read the documentation.");
3008 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3009 "MinSpareThreads of %d not allowed, increasing to 1",
3012 min_spare_threads = 1;
3015 /* max_spare_threads < min_spare_threads + threads_per_child
3016 * checked in ap_mpm_run()
3022 static void event_hooks(apr_pool_t * p)
3024 /* Our open_logs hook function must run before the core's, or stderr
3025 * will be redirected to a file, and the messages won't print to the
3028 static const char *const aszSucc[] = { "core.c", NULL };
3031 ap_hook_open_logs(event_open_logs, NULL, aszSucc, APR_HOOK_REALLY_FIRST);
3032 /* we need to set the MPM state before other pre-config hooks use MPM query
3033 * to retrieve it, so register as REALLY_FIRST
3035 ap_hook_pre_config(event_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
3036 ap_hook_check_config(event_check_config, NULL, NULL, APR_HOOK_MIDDLE);
3037 ap_hook_mpm(event_run, NULL, NULL, APR_HOOK_MIDDLE);
3038 ap_hook_mpm_query(event_query, NULL, NULL, APR_HOOK_MIDDLE);
3039 ap_hook_mpm_register_timed_callback(event_register_timed_callback, NULL, NULL,
3041 ap_hook_mpm_get_name(event_get_name, NULL, NULL, APR_HOOK_MIDDLE);
3044 static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy,
3047 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3052 ap_daemons_to_start = atoi(arg);
3056 static const char *set_min_spare_threads(cmd_parms * cmd, void *dummy,
3059 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3064 min_spare_threads = atoi(arg);
3068 static const char *set_max_spare_threads(cmd_parms * cmd, void *dummy,
3071 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3076 max_spare_threads = atoi(arg);
3080 static const char *set_max_workers(cmd_parms * cmd, void *dummy,
3083 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3087 if (!strcasecmp(cmd->cmd->name, "MaxClients")) {
3088 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL,
3089 "MaxClients is deprecated, use MaxRequestWorkers "
3092 max_workers = atoi(arg);
3096 static const char *set_threads_per_child(cmd_parms * cmd, void *dummy,
3099 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3104 threads_per_child = atoi(arg);
3107 static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg)
3109 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3114 server_limit = atoi(arg);
3118 static const char *set_thread_limit(cmd_parms * cmd, void *dummy,
3121 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3126 thread_limit = atoi(arg);
3130 static const char *set_worker_factor(cmd_parms * cmd, void *dummy,
3135 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3140 val = strtod(arg, &endptr);
3142 return "error parsing value";
3144 worker_factor = val * WORKER_FACTOR_SCALE;
3145 if (worker_factor == 0)
3151 static const command_rec event_cmds[] = {
3153 AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
3154 "Number of child processes launched at server startup"),
3155 AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF,
3156 "Maximum number of child processes for this run of Apache"),
3157 AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF,
3158 "Minimum number of idle threads, to handle request spikes"),
3159 AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF,
3160 "Maximum number of idle threads"),
3161 AP_INIT_TAKE1("MaxClients", set_max_workers, NULL, RSRC_CONF,
3162 "Deprecated name of MaxRequestWorkers"),
3163 AP_INIT_TAKE1("MaxRequestWorkers", set_max_workers, NULL, RSRC_CONF,
3164 "Maximum number of threads alive at the same time"),
3165 AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF,
3166 "Number of threads each child creates"),
3167 AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF,
3168 "Maximum number of worker threads per child process for this "
3169 "run of Apache - Upper limit for ThreadsPerChild"),
3170 AP_INIT_TAKE1("AsyncRequestWorkerFactor", set_worker_factor, NULL, RSRC_CONF,
3171 "How many additional connects will be accepted per idle "
3173 AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND,
3177 AP_DECLARE_MODULE(mpm_event) = {
3179 NULL, /* hook to run before apache parses args */
3180 NULL, /* create per-directory config structure */
3181 NULL, /* merge per-directory config structures */
3182 NULL, /* create per-server config structure */
3183 NULL, /* merge per-server config structures */
3184 event_cmds, /* command apr_table_t */
3185 event_hooks /* register_hooks */