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 typedef struct pollset_op_t {
196 timeout_type_e timeout_type;
201 APR_RING_HEAD(timeout_head_t, conn_state_t);
202 struct timeout_queue {
203 struct timeout_head_t head;
208 * Several timeout queues that use different timeouts, so that we always can
209 * simply append to the end.
210 * write_completion_q uses TimeOut
211 * keepalive_q uses KeepAliveTimeOut
212 * linger_q uses MAX_SECS_TO_LINGER
213 * short_linger_q uses SECONDS_TO_LINGER
215 static struct timeout_queue write_completion_q, keepalive_q, linger_q,
217 static apr_pollfd_t *listener_pollfd;
220 * Macros for accessing struct timeout_queue.
221 * For TO_QUEUE_APPEND and TO_QUEUE_REMOVE, timeout_mutex must be held.
223 #define TO_QUEUE_APPEND(q, el) \
225 APR_RING_INSERT_TAIL(&(q).head, el, conn_state_t, timeout_list); \
229 #define TO_QUEUE_REMOVE(q, el) \
231 APR_RING_REMOVE(el, timeout_list); \
235 #define TO_QUEUE_INIT(q) \
237 APR_RING_INIT(&(q).head, conn_state_t, timeout_list); \
241 #define TO_QUEUE_ELEM_INIT(el) APR_RING_ELEM_INIT(el, timeout_list)
244 * The pollset for sockets that are in any of the timeout queues. Currently
245 * we use the timeout_mutex to make sure that connections are added/removed
246 * atomically to/from both event_pollset and a timeout queue. Otherwise
247 * some confusion can happen under high load if timeout queues and pollset
249 * XXX: It should be possible to make the lock unnecessary in many or even all
252 static apr_pollset_t *event_pollset;
256 apr_pollset_t *pollset;
260 static serf_context_t *g_serf;
263 /* The structure used to pass unique initialization info to each thread */
271 /* Structure used to pass information to the thread responsible for
272 * creating the rest of the threads.
276 apr_thread_t **threads;
277 apr_thread_t *listener;
279 apr_threadattr_t *threadattr;
295 } listener_poll_type;
297 /* data retained by event across load/unload of the module
298 * allocated on first call to pre-config hook; located on
299 * subsequent calls to pre-config hook
301 typedef struct event_retained_data {
302 int first_server_limit;
303 int first_thread_limit;
305 int sick_child_detected;
306 ap_generation_t my_generation;
307 int volatile is_graceful; /* set from signal handler */
308 int maxclients_reported;
310 * The max child slot ever assigned, preserved across restarts. Necessary
311 * to deal with MaxRequestWorkers changes across AP_SIG_GRACEFUL restarts.
312 * We use this value to optimize routines that have to scan the entire
315 int max_daemons_limit;
317 * idle_spawn_rate is the number of children that will be spawned on the
318 * next maintenance cycle if there aren't enough idle servers. It is
319 * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
320 * without the need to spawn.
323 #ifndef MAX_SPAWN_RATE
324 #define MAX_SPAWN_RATE (32)
326 int hold_off_on_exponential_spawning;
327 } event_retained_data;
328 static event_retained_data *retained;
330 #define ID_FROM_CHILD_THREAD(c, t) ((c * thread_limit) + t)
332 static ap_event_pod_t *pod;
334 /* The event MPM respects a couple of runtime flags that can aid
335 * in debugging. Setting the -DNO_DETACH flag will prevent the root process
336 * from detaching from its controlling terminal. Additionally, setting
337 * the -DONE_PROCESS flag (which implies -DNO_DETACH) will get you the
338 * child_main loop running in the process which originally started up.
339 * This gives you a pretty nice debugging environment. (You'll get a SIGHUP
340 * early in standalone_main; just continue through. This is the server
341 * trying to kill off any child processes which it might have lying
342 * around --- Apache doesn't keep track of their pids, it just sends
343 * SIGHUP to the process group, ignoring it in the root process.
344 * Continue through and you'll be fine.).
347 static int one_process = 0;
350 int raise_sigstop_flags;
353 static apr_pool_t *pconf; /* Pool for config stuff */
354 static apr_pool_t *pchild; /* Pool for httpd child stuff */
356 static pid_t ap_my_pid; /* Linux getpid() doesn't work except in main
357 thread. Use this instead */
358 static pid_t parent_pid;
359 static apr_os_thread_t *listener_os_thread;
361 /* The LISTENER_SIGNAL signal will be sent from the main thread to the
362 * listener thread to wake it up for graceful termination (what a child
363 * process from an old generation does when the admin does "apachectl
364 * graceful"). This signal will be blocked in all threads of a child
365 * process except for the listener thread.
367 #define LISTENER_SIGNAL SIGHUP
369 /* An array of socket descriptors in use by each thread used to
370 * perform a non-graceful (forced) shutdown of the server.
372 static apr_socket_t **worker_sockets;
373 static ap_equeue_t **worker_equeues;
375 static void disable_listensocks(int process_slot)
378 for (i = 0; i < num_listensocks; i++) {
379 apr_pollset_remove(event_pollset, &listener_pollfd[i]);
381 ap_scoreboard_image->parent[process_slot].not_accepting = 1;
384 static void enable_listensocks(int process_slot)
387 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
388 "Accepting new connections again: "
389 "%u active conns, %u idle workers",
390 apr_atomic_read32(&connection_count),
391 ap_queue_info_get_idlers(worker_queue_info));
392 for (i = 0; i < num_listensocks; i++)
393 apr_pollset_add(event_pollset, &listener_pollfd[i]);
395 * XXX: This is not yet optimal. If many workers suddenly become available,
396 * XXX: the parent may kill some processes off too soon.
398 ap_scoreboard_image->parent[process_slot].not_accepting = 0;
401 static void close_worker_sockets(void)
404 for (i = 0; i < threads_per_child; i++) {
405 if (worker_sockets[i]) {
406 apr_socket_close(worker_sockets[i]);
407 worker_sockets[i] = NULL;
412 static void wakeup_listener(void)
414 listener_may_exit = 1;
415 if (!listener_os_thread) {
416 /* XXX there is an obscure path that this doesn't handle perfectly:
417 * right after listener thread is created but before
418 * listener_os_thread is set, the first worker thread hits an
419 * error and starts graceful termination
424 /* unblock the listener if it's waiting for a worker */
425 ap_queue_info_term(worker_queue_info);
428 * we should just be able to "kill(ap_my_pid, LISTENER_SIGNAL)" on all
429 * platforms and wake up the listener thread since it is the only thread
430 * with SIGHUP unblocked, but that doesn't work on Linux
432 #ifdef HAVE_PTHREAD_KILL
433 pthread_kill(*listener_os_thread, LISTENER_SIGNAL);
435 kill(ap_my_pid, LISTENER_SIGNAL);
440 #define ST_GRACEFUL 1
441 #define ST_UNGRACEFUL 2
443 static int terminate_mode = ST_INIT;
445 static void signal_threads(int mode)
447 if (terminate_mode == mode) {
450 terminate_mode = mode;
451 mpm_state = AP_MPMQ_STOPPING;
453 /* in case we weren't called from the listener thread, wake up the
458 /* for ungraceful termination, let the workers exit now;
459 * for graceful termination, the listener thread will notify the
460 * workers to exit once it has stopped accepting new connections
462 if (mode == ST_UNGRACEFUL) {
463 workers_may_exit = 1;
464 ap_queue_interrupt_all(worker_queue);
465 close_worker_sockets(); /* forcefully kill all current connections */
469 static int event_query(int query_code, int *result, apr_status_t *rv)
472 switch (query_code) {
473 case AP_MPMQ_MAX_DAEMON_USED:
474 *result = retained->max_daemons_limit;
476 case AP_MPMQ_IS_THREADED:
477 *result = AP_MPMQ_STATIC;
479 case AP_MPMQ_IS_FORKED:
480 *result = AP_MPMQ_DYNAMIC;
482 case AP_MPMQ_IS_ASYNC:
485 case AP_MPMQ_HAS_SERF:
488 case AP_MPMQ_HARD_LIMIT_DAEMONS:
489 *result = server_limit;
491 case AP_MPMQ_HARD_LIMIT_THREADS:
492 *result = thread_limit;
494 case AP_MPMQ_MAX_THREADS:
495 *result = threads_per_child;
497 case AP_MPMQ_MIN_SPARE_DAEMONS:
500 case AP_MPMQ_MIN_SPARE_THREADS:
501 *result = min_spare_threads;
503 case AP_MPMQ_MAX_SPARE_DAEMONS:
506 case AP_MPMQ_MAX_SPARE_THREADS:
507 *result = max_spare_threads;
509 case AP_MPMQ_MAX_REQUESTS_DAEMON:
510 *result = ap_max_requests_per_child;
512 case AP_MPMQ_MAX_DAEMONS:
513 *result = ap_daemons_limit;
515 case AP_MPMQ_MPM_STATE:
518 case AP_MPMQ_GENERATION:
519 *result = retained->my_generation;
528 static void event_note_child_killed(int childnum, pid_t pid, ap_generation_t gen)
530 if (childnum != -1) { /* child had a scoreboard slot? */
531 ap_run_child_status(ap_server_conf,
532 ap_scoreboard_image->parent[childnum].pid,
533 ap_scoreboard_image->parent[childnum].generation,
534 childnum, MPM_CHILD_EXITED);
535 ap_scoreboard_image->parent[childnum].pid = 0;
538 ap_run_child_status(ap_server_conf, pid, gen, -1, MPM_CHILD_EXITED);
542 static void event_note_child_started(int slot, pid_t pid)
544 ap_scoreboard_image->parent[slot].pid = pid;
545 ap_run_child_status(ap_server_conf,
546 ap_scoreboard_image->parent[slot].pid,
547 retained->my_generation, slot, MPM_CHILD_STARTED);
550 static void event_note_child_lost_slot(int slot, pid_t newpid)
552 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
553 "pid %" APR_PID_T_FMT " taking over scoreboard slot from "
554 "%" APR_PID_T_FMT "%s",
556 ap_scoreboard_image->parent[slot].pid,
557 ap_scoreboard_image->parent[slot].quiescing ?
558 " (quiescing)" : "");
559 ap_run_child_status(ap_server_conf,
560 ap_scoreboard_image->parent[slot].pid,
561 ap_scoreboard_image->parent[slot].generation,
562 slot, MPM_CHILD_LOST_SLOT);
563 /* Don't forget about this exiting child process, or we
564 * won't be able to kill it if it doesn't exit by the
565 * time the server is shut down.
567 ap_register_extra_mpm_process(ap_scoreboard_image->parent[slot].pid,
568 ap_scoreboard_image->parent[slot].generation);
571 static const char *event_get_name(void)
576 /* a clean exit from a child with proper cleanup */
577 static void clean_child_exit(int code) __attribute__ ((noreturn));
578 static void clean_child_exit(int code)
580 mpm_state = AP_MPMQ_STOPPING;
582 apr_pool_destroy(pchild);
586 event_note_child_killed(/* slot */ 0, 0, 0);
592 static void just_die(int sig)
597 /*****************************************************************
598 * Connection structures and accounting...
601 static int child_fatal;
603 /* volatile because they're updated from a signal handler */
604 static int volatile shutdown_pending;
605 static int volatile restart_pending;
607 static apr_status_t decrement_connection_count(void *dummy) {
608 apr_atomic_dec32(&connection_count);
613 * ap_start_shutdown() and ap_start_restart(), below, are a first stab at
614 * functions to initiate shutdown or restart without relying on signals.
615 * Previously this was initiated in sig_term() and restart() signal handlers,
616 * but we want to be able to start a shutdown/restart from other sources --
617 * e.g. on Win32, from the service manager. Now the service manager can
618 * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that
619 * these functions can also be called by the child processes, since global
620 * variables are no longer used to pass on the required action to the parent.
622 * These should only be called from the parent process itself, since the
623 * parent process will use the shutdown_pending and restart_pending variables
624 * to determine whether to shutdown or restart. The child process should
625 * call signal_parent() directly to tell the parent to die -- this will
626 * cause neither of those variable to be set, which the parent will
627 * assume means something serious is wrong (which it will be, for the
628 * child to force an exit) and so do an exit anyway.
631 static void ap_start_shutdown(int graceful)
633 mpm_state = AP_MPMQ_STOPPING;
634 if (shutdown_pending == 1) {
635 /* Um, is this _probably_ not an error, if the user has
636 * tried to do a shutdown twice quickly, so we won't
637 * worry about reporting it.
641 shutdown_pending = 1;
642 retained->is_graceful = graceful;
645 /* do a graceful restart if graceful == 1 */
646 static void ap_start_restart(int graceful)
648 mpm_state = AP_MPMQ_STOPPING;
649 if (restart_pending == 1) {
650 /* Probably not an error - don't bother reporting it */
654 retained->is_graceful = graceful;
657 static void sig_term(int sig)
659 ap_start_shutdown(sig == AP_SIG_GRACEFUL_STOP);
662 static void restart(int sig)
664 ap_start_restart(sig == AP_SIG_GRACEFUL);
667 static void set_signals(void)
669 #ifndef NO_USE_SIGACTION
674 ap_fatal_signal_setup(ap_server_conf, pconf);
677 #ifndef NO_USE_SIGACTION
678 sigemptyset(&sa.sa_mask);
681 sa.sa_handler = sig_term;
682 if (sigaction(SIGTERM, &sa, NULL) < 0)
683 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
684 "sigaction(SIGTERM)");
685 #ifdef AP_SIG_GRACEFUL_STOP
686 if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0)
687 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
688 "sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")");
691 if (sigaction(SIGINT, &sa, NULL) < 0)
692 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
693 "sigaction(SIGINT)");
696 sa.sa_handler = SIG_DFL;
697 if (sigaction(SIGXCPU, &sa, NULL) < 0)
698 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
699 "sigaction(SIGXCPU)");
702 /* For systems following the LFS standard, ignoring SIGXFSZ allows
703 * a write() beyond the 2GB limit to fail gracefully with E2BIG
704 * rather than terminate the process. */
705 sa.sa_handler = SIG_IGN;
706 if (sigaction(SIGXFSZ, &sa, NULL) < 0)
707 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
708 "sigaction(SIGXFSZ)");
711 sa.sa_handler = SIG_IGN;
712 if (sigaction(SIGPIPE, &sa, NULL) < 0)
713 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
714 "sigaction(SIGPIPE)");
717 /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy
719 sigaddset(&sa.sa_mask, SIGHUP);
720 sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL);
721 sa.sa_handler = restart;
722 if (sigaction(SIGHUP, &sa, NULL) < 0)
723 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
724 "sigaction(SIGHUP)");
725 if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0)
726 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
727 "sigaction(" AP_SIG_GRACEFUL_STRING ")");
731 apr_signal(SIGXCPU, SIG_DFL);
734 apr_signal(SIGXFSZ, SIG_IGN);
738 apr_signal(SIGTERM, sig_term);
740 apr_signal(SIGHUP, restart);
742 #ifdef AP_SIG_GRACEFUL
743 apr_signal(AP_SIG_GRACEFUL, restart);
744 #endif /* AP_SIG_GRACEFUL */
745 #ifdef AP_SIG_GRACEFUL_STOP
746 apr_signal(AP_SIG_GRACEFUL_STOP, sig_term);
747 #endif /* AP_SIG_GRACEFUL_STOP */
749 apr_signal(SIGPIPE, SIG_IGN);
755 static void process_pollop(pollset_op_t *op)
758 conn_state_t *cs = op->cs;
760 switch (op->timeout_type) {
761 case TIMEOUT_WRITE_COMPLETION:
762 TO_QUEUE_APPEND(write_completion_q, cs);
764 case TIMEOUT_KEEPALIVE:
765 TO_QUEUE_APPEND(keepalive_q, cs);
768 TO_QUEUE_APPEND(linger_q, cs);
770 case TIMEOUT_SHORT_LINGER:
771 TO_QUEUE_APPEND(short_linger_q, cs);
775 rv = apr_pollset_add(event_pollset, &op->cs->pfd);
777 if (rv != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rv)) {
778 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
779 "%s: apr_pollset_add failure", op->tag);
784 * close our side of the connection
785 * Pre-condition: cs is not in any timeout queue and not in the pollset,
786 * timeout_mutex is not locked
787 * return: 0 if connection is fully closed,
788 * 1 if connection is lingering
789 * may be called by listener or by worker thread.
790 * the eq may be null if called from the listener thread,
791 * and the pollset operations are done directly by this function.
793 static int start_lingering_close(conn_state_t *cs, ap_equeue_t *eq)
797 cs->c->sbh = NULL; /* prevent scoreboard updates from the listener
798 * worker will loop around soon and set SERVER_READY
801 if (ap_start_lingering_close(cs->c)) {
802 apr_pool_clear(cs->p);
803 ap_push_pool(worker_queue_info, cs->p);
807 apr_socket_t *csd = ap_get_conn_socket(cs->c);
812 v = ap_equeue_writer_value(eq);
818 rv = apr_socket_timeout_set(csd, 0);
819 AP_DEBUG_ASSERT(rv == APR_SUCCESS);
821 * If some module requested a shortened waiting period, only wait for
822 * 2s (SECONDS_TO_LINGER). This is useful for mitigating certain
825 if (apr_table_get(cs->c->notes, "short-lingering-close")) {
826 cs->expiration_time =
827 apr_time_now() + apr_time_from_sec(SECONDS_TO_LINGER);
828 v->timeout_type = TIMEOUT_SHORT_LINGER;
829 v->tag = "start_lingering_close(short)";
830 cs->state = CONN_STATE_LINGER_SHORT;
833 cs->expiration_time =
834 apr_time_now() + apr_time_from_sec(MAX_SECS_TO_LINGER);
835 v->timeout_type = TIMEOUT_LINGER;
836 v->tag = "start_lingering_close(normal)";
837 cs->state = CONN_STATE_LINGER_NORMAL;
840 cs->pfd.reqevents = APR_POLLIN | APR_POLLHUP | APR_POLLERR;
843 ap_equeue_writer_onward(eq);
844 apr_pollset_wakeup(event_pollset);
854 * forcibly close a lingering connection after the lingering period has
856 * Pre-condition: cs is not in any timeout queue and not in the pollset
857 * return: irrelevant (need same prototype as start_lingering_close)
859 static int stop_lingering_close(conn_state_t *cs, ap_equeue_t *eq)
862 apr_socket_t *csd = ap_get_conn_socket(cs->c);
863 ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf,
864 "socket reached timeout in lingering-close state");
865 rv = apr_socket_close(csd);
866 if (rv != APR_SUCCESS) {
867 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, "error closing socket");
870 apr_pool_clear(cs->p);
871 ap_push_pool(worker_queue_info, cs->p);
876 * process one connection in the worker
877 * return: 1 if the connection has been completed,
878 * 0 if it is still open and waiting for some event
880 static int process_socket(apr_thread_t *thd, apr_pool_t * p, apr_socket_t * sock,
887 long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num);
891 ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num);
893 if (cs == NULL) { /* This is a new connection */
894 listener_poll_type *pt = apr_pcalloc(p, sizeof(*pt));
895 cs = apr_pcalloc(p, sizeof(conn_state_t));
896 cs->bucket_alloc = apr_bucket_alloc_create(p);
897 c = ap_run_create_connection(p, ap_server_conf, sock,
898 conn_id, sbh, cs->bucket_alloc);
900 apr_bucket_alloc_destroy(cs->bucket_alloc);
902 ap_push_pool(worker_queue_info, p);
905 apr_atomic_inc32(&connection_count);
906 apr_pool_cleanup_register(c->pool, NULL, decrement_connection_count, apr_pool_cleanup_null);
907 c->current_thread = thd;
911 cs->pfd.desc_type = APR_POLL_SOCKET;
912 cs->pfd.reqevents = APR_POLLIN;
913 cs->pfd.desc.s = sock;
916 cs->pfd.client_data = pt;
918 ap_update_vhost_given_ip(c);
920 rc = ap_run_pre_connection(c, sock);
921 if (rc != OK && rc != DONE) {
922 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
923 "process_socket: connection aborted");
928 * XXX If the platform does not have a usable way of bundling
929 * accept() with a socket readability check, like Win32,
930 * and there are measurable delays before the
931 * socket is readable due to the first data packet arriving,
932 * it might be better to create the cs on the listener thread
933 * with the state set to CONN_STATE_CHECK_REQUEST_LINE_READABLE
935 * FreeBSD users will want to enable the HTTP accept filter
936 * module in their kernel for the highest performance
937 * When the accept filter is active, sockets are kept in the
938 * kernel until a HTTP request is received.
940 cs->state = CONN_STATE_READ_REQUEST_LINE;
946 c->current_thread = thd;
949 if (c->clogging_input_filters && !c->aborted) {
950 /* Since we have an input filter which 'cloggs' the input stream,
951 * like mod_ssl, lets just do the normal read from input filters,
952 * like the Worker MPM does.
954 ap_run_process_connection(c);
955 if (cs->state != CONN_STATE_SUSPENDED) {
956 cs->state = CONN_STATE_LINGER;
961 if (cs->state == CONN_STATE_READ_REQUEST_LINE) {
963 ap_run_process_connection(c);
965 /* state will be updated upon return
966 * fall thru to either wait for readability/timeout or
971 cs->state = CONN_STATE_LINGER;
975 if (cs->state == CONN_STATE_WRITE_COMPLETION) {
976 ap_filter_t *output_filter = c->output_filters;
978 ap_update_child_status_from_conn(sbh, SERVER_BUSY_WRITE, c);
979 while (output_filter->next != NULL) {
980 output_filter = output_filter->next;
982 rv = output_filter->frec->filter_func.out_func(output_filter, NULL);
983 if (rv != APR_SUCCESS) {
984 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c,
985 "network write failure in core output filter");
986 cs->state = CONN_STATE_LINGER;
988 else if (c->data_in_output_filters) {
989 /* Still in WRITE_COMPLETION_STATE:
990 * Set a write timeout for this connection, and let the
991 * event thread poll for writeability.
993 pollset_op_t *v = ap_equeue_writer_value(eq);
995 cs->expiration_time = ap_server_conf->timeout + apr_time_now();
996 cs->pfd.reqevents = APR_POLLOUT | APR_POLLHUP | APR_POLLERR;
999 v->timeout_type = TIMEOUT_WRITE_COMPLETION;
1000 v->tag = "process_socket(write_completion)";
1002 ap_equeue_writer_onward(eq);
1003 apr_pollset_wakeup(event_pollset);
1006 else if (c->keepalive != AP_CONN_KEEPALIVE || c->aborted ||
1007 listener_may_exit) {
1008 c->cs->state = CONN_STATE_LINGER;
1010 else if (c->data_in_input_filters) {
1011 cs->state = CONN_STATE_READ_REQUEST_LINE;
1015 cs->state = CONN_STATE_CHECK_REQUEST_LINE_READABLE;
1019 if (cs->state == CONN_STATE_LINGER) {
1020 if (!start_lingering_close(cs, eq)) {
1024 else if (cs->state == CONN_STATE_CHECK_REQUEST_LINE_READABLE) {
1027 /* It greatly simplifies the logic to use a single timeout value here
1028 * because the new element can just be added to the end of the list and
1029 * it will stay sorted in expiration time sequence. If brand new
1030 * sockets are sent to the event thread for a readability check, this
1031 * will be a slight behavior change - they use the non-keepalive
1032 * timeout today. With a normal client, the socket will be readable in
1033 * a few milliseconds anyway.
1035 cs->expiration_time = ap_server_conf->keep_alive_timeout +
1038 /* Add work to pollset. */
1039 v = ap_equeue_writer_value(eq);
1040 v->timeout_type = TIMEOUT_KEEPALIVE;
1042 cs->pfd.reqevents = APR_POLLIN;
1043 v->tag = "process_socket(keepalive)";
1044 ap_equeue_writer_onward(eq);
1045 apr_pollset_wakeup(event_pollset);
1050 /* requests_this_child has gone to zero or below. See if the admin coded
1051 "MaxConnectionsPerChild 0", and keep going in that case. Doing it this way
1052 simplifies the hot path in worker_thread */
1053 static void check_infinite_requests(void)
1055 if (ap_max_requests_per_child) {
1056 signal_threads(ST_GRACEFUL);
1059 requests_this_child = INT_MAX; /* keep going */
1063 static void close_listeners(int process_slot, int *closed) {
1066 disable_listensocks(process_slot);
1067 ap_close_listeners();
1070 ap_scoreboard_image->parent[process_slot].quiescing = 1;
1071 for (i = 0; i < threads_per_child; ++i) {
1072 ap_update_child_status_from_indexes(process_slot, i,
1073 SERVER_GRACEFUL, NULL);
1075 /* wake up the main thread */
1076 kill(ap_my_pid, SIGTERM);
1080 static void unblock_signal(int sig)
1084 sigemptyset(&sig_mask);
1085 sigaddset(&sig_mask, sig);
1086 #if defined(SIGPROCMASK_SETS_THREAD_MASK)
1087 sigprocmask(SIG_UNBLOCK, &sig_mask, NULL);
1089 pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL);
1093 static void dummy_signal_handler(int sig)
1095 /* XXX If specifying SIG_IGN is guaranteed to unblock a syscall,
1096 * then we don't need this goofy function.
1102 static apr_status_t s_socket_add(void *user_baton,
1106 s_baton_t *s = (s_baton_t*)user_baton;
1107 /* XXXXX: recycle listener_poll_types */
1108 listener_poll_type *pt = ap_malloc(sizeof(*pt));
1110 pt->baton = serf_baton;
1111 pfd->client_data = pt;
1112 return apr_pollset_add(s->pollset, pfd);
1115 static apr_status_t s_socket_remove(void *user_baton,
1119 s_baton_t *s = (s_baton_t*)user_baton;
1120 listener_poll_type *pt = pfd->client_data;
1122 return apr_pollset_remove(s->pollset, pfd);
1126 static apr_status_t init_pollset(apr_pool_t *p)
1129 s_baton_t *baton = NULL;
1132 listener_poll_type *pt;
1135 TO_QUEUE_INIT(write_completion_q);
1136 TO_QUEUE_INIT(keepalive_q);
1137 TO_QUEUE_INIT(linger_q);
1138 TO_QUEUE_INIT(short_linger_q);
1140 listener_pollfd = apr_palloc(p, sizeof(apr_pollfd_t) * num_listensocks);
1141 for (lr = ap_listeners; lr != NULL; lr = lr->next, i++) {
1143 AP_DEBUG_ASSERT(i < num_listensocks);
1144 pfd = &listener_pollfd[i];
1145 pt = apr_pcalloc(p, sizeof(*pt));
1146 pfd->desc_type = APR_POLL_SOCKET;
1147 pfd->desc.s = lr->sd;
1148 pfd->reqevents = APR_POLLIN;
1150 pt->type = PT_ACCEPT;
1153 pfd->client_data = pt;
1155 apr_socket_opt_set(pfd->desc.s, APR_SO_NONBLOCK, 1);
1156 apr_pollset_add(event_pollset, pfd);
1158 lr->accept_func = ap_unixd_accept;
1162 baton = apr_pcalloc(p, sizeof(*baton));
1163 baton->pollset = event_pollset;
1164 /* TODO: subpools, threads, reuse, etc. -- currently use malloc() inside :( */
1167 g_serf = serf_context_create_ex(baton,
1169 s_socket_remove, p);
1171 ap_register_provider(p, "mpm_serf",
1172 "instance", "0", g_serf);
1179 static apr_status_t push_timer2worker(timer_event_t* te)
1181 return ap_queue_push_timer(worker_queue, te);
1185 * Pre-condition: pfd->cs is neither in pollset nor timeout queue
1186 * this function may only be called by the listener
1188 static apr_status_t push2worker(const apr_pollfd_t * pfd,
1189 apr_pollset_t * pollset)
1191 listener_poll_type *pt = (listener_poll_type *) pfd->client_data;
1192 conn_state_t *cs = (conn_state_t *) pt->baton;
1195 rc = ap_queue_push(worker_queue, cs->pfd.desc.s, cs, cs->p);
1196 if (rc != APR_SUCCESS) {
1197 /* trash the connection; we couldn't queue the connected
1198 * socket to a worker
1200 apr_bucket_alloc_destroy(cs->bucket_alloc);
1201 apr_socket_close(cs->pfd.desc.s);
1202 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1203 ap_server_conf, "push2worker: ap_queue_push failed");
1204 apr_pool_clear(cs->p);
1205 ap_push_pool(worker_queue_info, cs->p);
1212 * If *have_idle_worker_p == 0, reserve a worker thread, and set
1213 * *have_idle_worker_p = 1.
1214 * If *have_idle_worker_p is already 1, will do nothing.
1215 * If blocking == 1, block if all workers are currently busy.
1216 * If no worker was available immediately, will set *all_busy to 1.
1217 * XXX: If there are no workers, we should not block immediately but
1218 * XXX: close all keep-alive connections first.
1220 static void get_worker(int *have_idle_worker_p, int blocking, int *all_busy)
1224 if (*have_idle_worker_p) {
1225 /* already reserved a worker thread - must have hit a
1226 * transient error on a previous pass
1232 rc = ap_queue_info_wait_for_idler(worker_queue_info, all_busy);
1234 rc = ap_queue_info_try_get_idler(worker_queue_info);
1236 if (rc == APR_SUCCESS) {
1237 *have_idle_worker_p = 1;
1239 else if (!blocking && rc == APR_EAGAIN) {
1242 else if (!APR_STATUS_IS_EOF(rc)) {
1243 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
1244 "ap_queue_info_wait_for_idler failed. "
1245 "Attempting to shutdown process gracefully");
1246 signal_threads(ST_GRACEFUL);
1250 /* XXXXXX: Convert to skiplist or other better data structure
1251 * (yes, this is VERY VERY VERY VERY BAD)
1254 /* Structures to reuse */
1255 static APR_RING_HEAD(timer_free_ring_t, timer_event_t) timer_free_ring;
1257 static APR_RING_HEAD(timer_ring_t, timer_event_t) timer_ring;
1259 static apr_thread_mutex_t *g_timer_ring_mtx;
1261 static apr_status_t event_register_timed_callback(apr_time_t t,
1262 ap_mpm_callback_fn_t *cbfn,
1268 /* oh yeah, and make locking smarter/fine grained. */
1269 apr_thread_mutex_lock(g_timer_ring_mtx);
1271 if (!APR_RING_EMPTY(&timer_free_ring, timer_event_t, link)) {
1272 te = APR_RING_FIRST(&timer_free_ring);
1273 APR_RING_REMOVE(te, link);
1276 /* XXXXX: lol, pool allocation without a context from any thread.Yeah. Right. MPMs Suck. */
1277 te = ap_malloc(sizeof(timer_event_t));
1278 APR_RING_ELEM_INIT(te, link);
1283 /* XXXXX: optimize */
1284 te->when = t + apr_time_now();
1286 /* Okay, insert sorted by when.. */
1287 for (ep = APR_RING_FIRST(&timer_ring);
1288 ep != APR_RING_SENTINEL(&timer_ring,
1289 timer_event_t, link);
1290 ep = APR_RING_NEXT(ep, link))
1292 if (ep->when > te->when) {
1294 APR_RING_INSERT_BEFORE(ep, te, link);
1300 APR_RING_INSERT_TAIL(&timer_ring, te, timer_event_t, link);
1303 apr_thread_mutex_unlock(g_timer_ring_mtx);
1309 * Close socket and clean up if remote closed its end while we were in
1311 * Only to be called in the listener thread;
1312 * Pre-condition: cs is in one of the linger queues and in the pollset
1314 static void process_lingering_close(conn_state_t *cs, const apr_pollfd_t *pfd)
1316 apr_socket_t *csd = ap_get_conn_socket(cs->c);
1317 char dummybuf[2048];
1320 struct timeout_queue *q;
1321 q = (cs->state == CONN_STATE_LINGER_SHORT) ? &short_linger_q : &linger_q;
1323 /* socket is already in non-blocking state */
1325 nbytes = sizeof(dummybuf);
1326 rv = apr_socket_recv(csd, dummybuf, &nbytes);
1327 } while (rv == APR_SUCCESS);
1329 if (!APR_STATUS_IS_EOF(rv)) {
1333 rv = apr_pollset_remove(event_pollset, pfd);
1334 AP_DEBUG_ASSERT(rv == APR_SUCCESS);
1336 rv = apr_socket_close(csd);
1337 AP_DEBUG_ASSERT(rv == APR_SUCCESS);
1339 TO_QUEUE_REMOVE(*q, cs);
1340 TO_QUEUE_ELEM_INIT(cs);
1342 apr_pool_clear(cs->p);
1343 ap_push_pool(worker_queue_info, cs->p);
1346 /* call 'func' for all elements of 'q' with timeout less than 'timeout_time'.
1347 * Pre-condition: timeout_mutex must already be locked
1348 * Post-condition: timeout_mutex will be locked again
1350 static void process_timeout_queue(struct timeout_queue *q,
1351 apr_time_t timeout_time,
1352 int (*func)(conn_state_t *, ap_equeue_t *eq))
1355 conn_state_t *first, *cs, *last;
1360 AP_DEBUG_ASSERT(!APR_RING_EMPTY(&q->head, conn_state_t, timeout_list));
1362 cs = first = APR_RING_FIRST(&q->head);
1363 while (cs != APR_RING_SENTINEL(&q->head, conn_state_t, timeout_list)
1364 && cs->expiration_time < timeout_time) {
1366 rv = apr_pollset_remove(event_pollset, &cs->pfd);
1367 if (rv != APR_SUCCESS && !APR_STATUS_IS_NOTFOUND(rv)) {
1368 ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, cs->c,
1369 "apr_pollset_remove failed");
1371 cs = APR_RING_NEXT(cs, timeout_list);
1377 APR_RING_UNSPLICE(first, last, timeout_list);
1378 AP_DEBUG_ASSERT(q->count >= count);
1381 cs = APR_RING_NEXT(first, timeout_list);
1382 TO_QUEUE_ELEM_INIT(first);
1389 static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy)
1394 proc_info *ti = dummy;
1395 int process_slot = ti->pid;
1396 apr_pool_t *tpool = apr_thread_pool_get(thd);
1398 apr_pool_t *ptrans; /* Pool for per-transaction stuff */
1400 int have_idle_worker = 0;
1402 const apr_pollfd_t *out_pfd;
1403 apr_int32_t num = 0;
1404 apr_interval_time_t timeout_interval;
1405 apr_time_t timeout_time = 0, now, last_log;
1406 listener_poll_type *pt;
1407 int closed = 0, listeners_disabled = 0;
1409 last_log = apr_time_now();
1412 /* the following times out events that are really close in the future
1413 * to prevent extra poll calls
1415 * current value is .1 second
1417 #define TIMEOUT_FUDGE_FACTOR 100000
1418 #define EVENT_FUDGE_FACTOR 10000
1420 rc = init_pollset(tpool);
1421 if (rc != APR_SUCCESS) {
1422 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
1423 "failed to initialize pollset, "
1424 "attempting to shutdown process gracefully");
1425 signal_threads(ST_GRACEFUL);
1429 /* Unblock the signal used to wake this thread up, and set a handler for
1432 unblock_signal(LISTENER_SIGNAL);
1433 apr_signal(LISTENER_SIGNAL, dummy_signal_handler);
1436 int workers_were_busy = 0;
1437 if (listener_may_exit) {
1438 close_listeners(process_slot, &closed);
1439 if (terminate_mode == ST_UNGRACEFUL
1440 || apr_atomic_read32(&connection_count) == 0)
1444 if (requests_this_child <= 0) {
1445 check_infinite_requests();
1448 now = apr_time_now();
1449 if (APLOGtrace6(ap_server_conf)) {
1450 /* trace log status every second */
1451 if (now - last_log > apr_time_from_msec(1000)) {
1453 ap_log_error(APLOG_MARK, APLOG_TRACE6, 0, ap_server_conf,
1454 "connections: %d (write-completion: %d "
1455 "keep-alive: %d lingering: %d)",
1456 connection_count, write_completion_q.count,
1458 linger_q.count + short_linger_q.count);
1462 apr_thread_mutex_lock(g_timer_ring_mtx);
1463 if (!APR_RING_EMPTY(&timer_ring, timer_event_t, link)) {
1464 te = APR_RING_FIRST(&timer_ring);
1465 if (te->when > now) {
1466 timeout_interval = te->when - now;
1469 timeout_interval = 1;
1473 timeout_interval = apr_time_from_msec(100);
1475 apr_thread_mutex_unlock(g_timer_ring_mtx);
1478 rc = serf_context_prerun(g_serf);
1479 if (rc != APR_SUCCESS) {
1480 /* TOOD: what should do here? ugh. */
1483 rc = apr_pollset_poll(event_pollset, timeout_interval, &num, &out_pfd);
1484 if (rc != APR_SUCCESS
1485 && !APR_STATUS_IS_EINTR(rc)
1486 && !APR_STATUS_IS_TIMEUP(rc)) {
1487 ap_log_error(APLOG_MARK, APLOG_CRIT, rc, ap_server_conf,
1488 "apr_pollset_poll failed. Attempting to "
1489 "shutdown process gracefully");
1490 signal_threads(ST_GRACEFUL);
1493 if (listener_may_exit) {
1494 close_listeners(process_slot, &closed);
1495 if (terminate_mode == ST_UNGRACEFUL
1496 || apr_atomic_read32(&connection_count) == 0)
1500 now = apr_time_now();
1501 apr_thread_mutex_lock(g_timer_ring_mtx);
1502 for (ep = APR_RING_FIRST(&timer_ring);
1503 ep != APR_RING_SENTINEL(&timer_ring,
1504 timer_event_t, link);
1505 ep = APR_RING_FIRST(&timer_ring))
1507 if (ep->when < now + EVENT_FUDGE_FACTOR) {
1508 APR_RING_REMOVE(ep, link);
1509 push_timer2worker(ep);
1515 apr_thread_mutex_unlock(g_timer_ring_mtx);
1518 pt = (listener_poll_type *) out_pfd->client_data;
1519 if (pt->type == PT_CSD) {
1520 /* one of the sockets is readable */
1521 struct timeout_queue *remove_from_q = &write_completion_q;
1523 cs = (conn_state_t *) pt->baton;
1524 switch (cs->state) {
1525 case CONN_STATE_CHECK_REQUEST_LINE_READABLE:
1526 cs->state = CONN_STATE_READ_REQUEST_LINE;
1527 remove_from_q = &keepalive_q;
1528 /* don't wait for a worker for a keepalive request */
1531 case CONN_STATE_WRITE_COMPLETION:
1532 get_worker(&have_idle_worker, blocking,
1533 &workers_were_busy);
1534 TO_QUEUE_REMOVE(*remove_from_q, cs);
1535 rc = apr_pollset_remove(event_pollset, &cs->pfd);
1538 * Some of the pollset backends, like KQueue or Epoll
1539 * automagically remove the FD if the socket is closed,
1540 * therefore, we can accept _SUCCESS or _NOTFOUND,
1541 * and we still want to keep going
1543 if (rc != APR_SUCCESS && !APR_STATUS_IS_NOTFOUND(rc)) {
1544 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
1545 "pollset remove failed");
1546 start_lingering_close(cs, NULL);
1550 TO_QUEUE_ELEM_INIT(cs);
1551 /* If we didn't get a worker immediately for a keep-alive
1552 * request, we close the connection, so that the client can
1553 * re-connect to a different process.
1555 if (!have_idle_worker) {
1556 start_lingering_close(cs, NULL);
1559 rc = push2worker(out_pfd, event_pollset);
1560 if (rc != APR_SUCCESS) {
1561 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1562 ap_server_conf, "push2worker failed");
1565 have_idle_worker = 0;
1568 case CONN_STATE_LINGER_NORMAL:
1569 case CONN_STATE_LINGER_SHORT:
1570 process_lingering_close(cs, out_pfd);
1573 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1575 "event_loop: unexpected state %d",
1580 else if (pt->type == PT_ACCEPT) {
1581 int skip_accept = 0;
1582 int connection_count_local = connection_count;
1584 /* A Listener Socket is ready for an accept() */
1585 if (workers_were_busy) {
1587 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1588 "All workers busy, not accepting new conns"
1591 else if (listeners_disabled) {
1592 listeners_disabled = 0;
1593 enable_listensocks(process_slot);
1595 else if (connection_count_local > threads_per_child
1596 + ap_queue_info_get_idlers(worker_queue_info) *
1597 worker_factor / WORKER_FACTOR_SCALE)
1600 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1601 "Too many open connections (%u), "
1602 "not accepting new conns in this process",
1603 connection_count_local);
1604 ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
1606 ap_queue_info_get_idlers(worker_queue_info));
1609 if (skip_accept == 0) {
1610 lr = (ap_listen_rec *) pt->baton;
1611 ap_pop_pool(&ptrans, worker_queue_info);
1613 if (ptrans == NULL) {
1614 /* create a new transaction pool for each accepted socket */
1615 apr_allocator_t *allocator;
1617 apr_allocator_create(&allocator);
1618 apr_allocator_max_free_set(allocator,
1620 apr_pool_create_ex(&ptrans, pconf, NULL, allocator);
1621 apr_allocator_owner_set(allocator, ptrans);
1622 if (ptrans == NULL) {
1623 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1625 "Failed to create transaction pool");
1626 signal_threads(ST_GRACEFUL);
1630 apr_pool_tag(ptrans, "transaction");
1632 get_worker(&have_idle_worker, 1, &workers_were_busy);
1633 rc = lr->accept_func(&csd, lr, ptrans);
1635 /* later we trash rv and rely on csd to indicate
1638 AP_DEBUG_ASSERT(rc == APR_SUCCESS || !csd);
1640 if (rc == APR_EGENERAL) {
1641 /* E[NM]FILE, ENOMEM, etc */
1642 resource_shortage = 1;
1643 signal_threads(ST_GRACEFUL);
1647 rc = ap_queue_push(worker_queue, csd, NULL, ptrans);
1648 if (rc != APR_SUCCESS) {
1649 /* trash the connection; we couldn't queue the connected
1650 * socket to a worker
1652 apr_socket_close(csd);
1653 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1655 "ap_queue_push failed");
1656 apr_pool_clear(ptrans);
1657 ap_push_pool(worker_queue_info, ptrans);
1660 have_idle_worker = 0;
1664 apr_pool_clear(ptrans);
1665 ap_push_pool(worker_queue_info, ptrans);
1668 } /* if:else on pt->type */
1670 else if (pt->type == PT_SERF) {
1671 /* send socket to serf. */
1672 /* XXXX: this doesn't require get_worker() */
1673 serf_event_trigger(g_serf, pt->baton, out_pfd);
1678 } /* while for processing poll */
1681 /* TODO: break out to separate function */
1684 for (i = 0; i < threads_per_child; i++) {
1685 ap_equeue_t *eq = worker_equeues[i];
1686 pollset_op_t *op = NULL;
1688 while ((op = ap_equeue_reader_next(eq)) != NULL) {
1694 /* XXX possible optimization: stash the current time for use as
1695 * r->request_time for new requests
1697 now = apr_time_now();
1698 /* we only do this once per 0.1s (TIMEOUT_FUDGE_FACTOR) */
1699 if (now > timeout_time) {
1700 struct process_score *ps;
1701 timeout_time = now + TIMEOUT_FUDGE_FACTOR;
1703 /* handle timed out sockets */
1705 /* Step 1: keepalive timeouts */
1706 /* If all workers are busy, we kill older keep-alive connections so that they
1707 * may connect to another process.
1709 if (workers_were_busy && keepalive_q.count) {
1710 ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
1711 "All workers are busy, will close %d keep-alive "
1714 process_timeout_queue(&keepalive_q,
1715 timeout_time + ap_server_conf->keep_alive_timeout,
1716 start_lingering_close);
1719 process_timeout_queue(&keepalive_q, timeout_time,
1720 start_lingering_close);
1722 /* Step 2: write completion timeouts */
1723 process_timeout_queue(&write_completion_q, timeout_time, start_lingering_close);
1724 /* Step 3: (normal) lingering close completion timeouts */
1725 process_timeout_queue(&linger_q, timeout_time, stop_lingering_close);
1726 /* Step 4: (short) lingering close completion timeouts */
1727 process_timeout_queue(&short_linger_q, timeout_time, stop_lingering_close);
1729 ps = ap_get_scoreboard_process(process_slot);
1730 ps->write_completion = write_completion_q.count;
1731 ps->lingering_close = linger_q.count + short_linger_q.count;
1732 ps->keep_alive = keepalive_q.count;
1734 ps->connections = apr_atomic_read32(&connection_count);
1735 /* XXX: should count CONN_STATE_SUSPENDED and set ps->suspended */
1737 if (listeners_disabled && !workers_were_busy &&
1738 (int)apr_atomic_read32(&connection_count) <
1739 ((int)ap_queue_info_get_idlers(worker_queue_info) - 1) *
1740 worker_factor / WORKER_FACTOR_SCALE + threads_per_child)
1742 listeners_disabled = 0;
1743 enable_listensocks(process_slot);
1746 * XXX: do we need to set some timeout that re-enables the listensocks
1747 * XXX: in case no other event occurs?
1749 } /* listener main loop */
1751 close_listeners(process_slot, &closed);
1752 ap_queue_term(worker_queue);
1754 apr_thread_exit(thd, APR_SUCCESS);
1758 /* XXX For ungraceful termination/restart, we definitely don't want to
1759 * wait for active connections to finish but we may want to wait
1760 * for idle workers to get out of the queue code and release mutexes,
1761 * since those mutexes are cleaned up pretty soon and some systems
1762 * may not react favorably (i.e., segfault) if operations are attempted
1763 * on cleaned-up mutexes.
1765 static void *APR_THREAD_FUNC worker_thread(apr_thread_t * thd, void *dummy)
1767 proc_info *ti = dummy;
1768 int process_slot = ti->pid;
1769 int thread_slot = ti->tid;
1770 apr_socket_t *csd = NULL;
1772 apr_pool_t *ptrans; /* Pool for per-transaction stuff */
1775 timer_event_t *te = NULL;
1776 ap_equeue_t *eq = worker_equeues[thread_slot];
1780 ap_scoreboard_image->servers[process_slot][thread_slot].pid = ap_my_pid;
1781 ap_scoreboard_image->servers[process_slot][thread_slot].tid = apr_os_thread_current();
1782 ap_scoreboard_image->servers[process_slot][thread_slot].generation = retained->my_generation;
1783 ap_update_child_status_from_indexes(process_slot, thread_slot,
1784 SERVER_STARTING, NULL);
1786 while (!workers_may_exit) {
1788 rv = ap_queue_info_set_idle(worker_queue_info, NULL);
1789 if (rv != APR_SUCCESS) {
1790 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
1791 "ap_queue_info_set_idle failed. Attempting to "
1792 "shutdown process gracefully.");
1793 signal_threads(ST_GRACEFUL);
1799 ap_update_child_status_from_indexes(process_slot, thread_slot,
1800 dying ? SERVER_GRACEFUL : SERVER_READY, NULL);
1802 if (workers_may_exit) {
1807 rv = ap_queue_pop_something(worker_queue, &csd, &cs, &ptrans, &te);
1809 if (rv != APR_SUCCESS) {
1810 /* We get APR_EOF during a graceful shutdown once all the
1811 * connections accepted by this server process have been handled.
1813 if (APR_STATUS_IS_EOF(rv)) {
1816 /* We get APR_EINTR whenever ap_queue_pop() has been interrupted
1817 * from an explicit call to ap_queue_interrupt_all(). This allows
1818 * us to unblock threads stuck in ap_queue_pop() when a shutdown
1821 * If workers_may_exit is set and this is ungraceful termination/
1822 * restart, we are bound to get an error on some systems (e.g.,
1823 * AIX, which sanity-checks mutex operations) since the queue
1824 * may have already been cleaned up. Don't log the "error" if
1825 * workers_may_exit is set.
1827 else if (APR_STATUS_IS_EINTR(rv)) {
1830 /* We got some other error. */
1831 else if (!workers_may_exit) {
1832 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1833 "ap_queue_pop failed");
1838 te->cbfunc(te->baton);
1841 apr_thread_mutex_lock(g_timer_ring_mtx);
1842 APR_RING_INSERT_TAIL(&timer_free_ring, te, timer_event_t, link);
1843 apr_thread_mutex_unlock(g_timer_ring_mtx);
1848 worker_sockets[thread_slot] = csd;
1849 rv = process_socket(thd, ptrans, csd, cs, eq, process_slot, thread_slot);
1851 requests_this_child--;
1853 worker_sockets[thread_slot] = NULL;
1857 ap_update_child_status_from_indexes(process_slot, thread_slot,
1858 dying ? SERVER_DEAD :
1860 (request_rec *) NULL);
1862 apr_thread_exit(thd, APR_SUCCESS);
1866 static int check_signal(int signum)
1878 static void create_listener_thread(thread_starter * ts)
1880 int my_child_num = ts->child_num_arg;
1881 apr_threadattr_t *thread_attr = ts->threadattr;
1885 my_info = (proc_info *) ap_malloc(sizeof(proc_info));
1886 my_info->pid = my_child_num;
1887 my_info->tid = -1; /* listener thread doesn't have a thread slot */
1889 rv = apr_thread_create(&ts->listener, thread_attr, listener_thread,
1891 if (rv != APR_SUCCESS) {
1892 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1893 "apr_thread_create: unable to create listener thread");
1894 /* let the parent decide how bad this really is */
1895 clean_child_exit(APEXIT_CHILDSICK);
1897 apr_os_thread_get(&listener_os_thread, ts->listener);
1900 /* XXX under some circumstances not understood, children can get stuck
1901 * in start_threads forever trying to take over slots which will
1902 * never be cleaned up; for now there is an APLOG_DEBUG message issued
1903 * every so often when this condition occurs
1905 static void *APR_THREAD_FUNC start_threads(apr_thread_t * thd, void *dummy)
1907 thread_starter *ts = dummy;
1908 apr_thread_t **threads = ts->threads;
1909 apr_threadattr_t *thread_attr = ts->threadattr;
1910 int child_num_arg = ts->child_num_arg;
1911 int my_child_num = child_num_arg;
1915 int threads_created = 0;
1916 int listener_started = 0;
1918 int prev_threads_created;
1919 int max_recycled_pools = -1;
1921 /* We must create the fd queues before we start up the listener
1922 * and worker threads. */
1923 worker_queue = apr_pcalloc(pchild, sizeof(*worker_queue));
1924 rv = ap_queue_init(worker_queue, threads_per_child, pchild);
1925 if (rv != APR_SUCCESS) {
1926 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1927 "ap_queue_init() failed");
1928 clean_child_exit(APEXIT_CHILDFATAL);
1931 if (ap_max_mem_free != APR_ALLOCATOR_MAX_FREE_UNLIMITED) {
1932 /* If we want to conserve memory, let's not keep an unlimited number of
1933 * pools & allocators.
1934 * XXX: This should probably be a separate config directive
1936 max_recycled_pools = threads_per_child * 3 / 4 ;
1938 rv = ap_queue_info_create(&worker_queue_info, pchild,
1939 threads_per_child, max_recycled_pools);
1940 if (rv != APR_SUCCESS) {
1941 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1942 "ap_queue_info_create() failed");
1943 clean_child_exit(APEXIT_CHILDFATAL);
1946 /* Create the main pollset */
1947 rv = apr_pollset_create(&event_pollset,
1948 threads_per_child, /* XXX don't we need more, to handle
1949 * connections in K-A or lingering
1952 pchild, APR_POLLSET_WAKEABLE|APR_POLLSET_NOCOPY);
1953 if (rv != APR_SUCCESS) {
1954 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
1955 "apr_pollset_create failed; check system or user limits");
1956 clean_child_exit(APEXIT_CHILDFATAL);
1959 worker_sockets = apr_pcalloc(pchild, threads_per_child
1960 * sizeof(apr_socket_t *));
1962 worker_equeues = apr_palloc(pchild, threads_per_child * sizeof(ap_equeue_t*));
1964 for (i = 0; i < threads_per_child; i++) {
1965 ap_equeue_t* eq = NULL;
1966 /* TODO: research/test optimal size of queue here */
1967 ap_equeue_create(pchild, 16, sizeof(pollset_op_t), &eq);
1968 /* same as thread ID */
1969 worker_equeues[i] = eq;
1972 loops = prev_threads_created = 0;
1974 /* threads_per_child does not include the listener thread */
1975 for (i = 0; i < threads_per_child; i++) {
1977 ap_scoreboard_image->servers[child_num_arg][i].status;
1979 if (status != SERVER_GRACEFUL && status != SERVER_DEAD) {
1983 my_info = (proc_info *) ap_malloc(sizeof(proc_info));
1984 my_info->pid = my_child_num;
1988 /* We are creating threads right now */
1989 ap_update_child_status_from_indexes(my_child_num, i,
1990 SERVER_STARTING, NULL);
1991 /* We let each thread update its own scoreboard entry. This is
1992 * done because it lets us deal with tid better.
1994 rv = apr_thread_create(&threads[i], thread_attr,
1995 worker_thread, my_info, pchild);
1996 if (rv != APR_SUCCESS) {
1997 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1998 "apr_thread_create: unable to create worker thread");
1999 /* let the parent decide how bad this really is */
2000 clean_child_exit(APEXIT_CHILDSICK);
2005 /* Start the listener only when there are workers available */
2006 if (!listener_started && threads_created) {
2007 create_listener_thread(ts);
2008 listener_started = 1;
2012 if (start_thread_may_exit || threads_created == threads_per_child) {
2015 /* wait for previous generation to clean up an entry */
2016 apr_sleep(apr_time_from_sec(1));
2018 if (loops % 120 == 0) { /* every couple of minutes */
2019 if (prev_threads_created == threads_created) {
2020 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
2021 "child %" APR_PID_T_FMT " isn't taking over "
2022 "slots very quickly (%d of %d)",
2023 ap_my_pid, threads_created,
2026 prev_threads_created = threads_created;
2030 /* What state should this child_main process be listed as in the
2032 * ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING,
2033 * (request_rec *) NULL);
2035 * This state should be listed separately in the scoreboard, in some kind
2036 * of process_status, not mixed in with the worker threads' status.
2037 * "life_status" is almost right, but it's in the worker's structure, and
2038 * the name could be clearer. gla
2040 apr_thread_exit(thd, APR_SUCCESS);
2044 static void join_workers(apr_thread_t * listener, apr_thread_t ** threads)
2047 apr_status_t rv, thread_rv;
2052 /* deal with a rare timing window which affects waking up the
2053 * listener thread... if the signal sent to the listener thread
2054 * is delivered between the time it verifies that the
2055 * listener_may_exit flag is clear and the time it enters a
2056 * blocking syscall, the signal didn't do any good... work around
2057 * that by sleeping briefly and sending it again
2061 while (iter < 10 && !dying) {
2062 /* listener has not stopped accepting yet */
2063 apr_sleep(apr_time_make(0, 500000));
2068 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
2069 "the listener thread didn't stop accepting");
2072 rv = apr_thread_join(&thread_rv, listener);
2073 if (rv != APR_SUCCESS) {
2074 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
2075 "apr_thread_join: unable to join listener thread");
2080 for (i = 0; i < threads_per_child; i++) {
2081 if (threads[i]) { /* if we ever created this thread */
2082 rv = apr_thread_join(&thread_rv, threads[i]);
2083 if (rv != APR_SUCCESS) {
2084 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
2085 "apr_thread_join: unable to join worker "
2092 static void join_start_thread(apr_thread_t * start_thread_id)
2094 apr_status_t rv, thread_rv;
2096 start_thread_may_exit = 1; /* tell it to give up in case it is still
2097 * trying to take over slots from a
2098 * previous generation
2100 rv = apr_thread_join(&thread_rv, start_thread_id);
2101 if (rv != APR_SUCCESS) {
2102 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
2103 "apr_thread_join: unable to join the start " "thread");
2107 static void child_main(int child_num_arg)
2109 apr_thread_t **threads;
2112 apr_threadattr_t *thread_attr;
2113 apr_thread_t *start_thread_id;
2115 mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
2118 ap_my_pid = getpid();
2119 ap_fatal_signal_child_setup(ap_server_conf);
2120 apr_pool_create(&pchild, pconf);
2122 /*stuff to do before we switch id's, so we have permissions. */
2123 ap_reopen_scoreboard(pchild, NULL, 0);
2125 if (ap_run_drop_privileges(pchild, ap_server_conf)) {
2126 clean_child_exit(APEXIT_CHILDFATAL);
2129 apr_thread_mutex_create(&g_timer_ring_mtx, APR_THREAD_MUTEX_DEFAULT, pchild);
2130 APR_RING_INIT(&timer_free_ring, timer_event_t, link);
2131 APR_RING_INIT(&timer_ring, timer_event_t, link);
2132 ap_run_child_init(pchild, ap_server_conf);
2134 /* done with init critical section */
2136 /* Just use the standard apr_setup_signal_thread to block all signals
2137 * from being received. The child processes no longer use signals for
2138 * any communication with the parent process.
2140 rv = apr_setup_signal_thread();
2141 if (rv != APR_SUCCESS) {
2142 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
2143 "Couldn't initialize signal thread");
2144 clean_child_exit(APEXIT_CHILDFATAL);
2147 if (ap_max_requests_per_child) {
2148 requests_this_child = ap_max_requests_per_child;
2151 /* coding a value of zero means infinity */
2152 requests_this_child = INT_MAX;
2155 /* Setup worker threads */
2157 /* clear the storage; we may not create all our threads immediately,
2158 * and we want a 0 entry to indicate a thread which was not created
2160 threads = ap_calloc(threads_per_child, sizeof(apr_thread_t *));
2161 ts = apr_palloc(pchild, sizeof(*ts));
2163 apr_threadattr_create(&thread_attr, pchild);
2164 /* 0 means PTHREAD_CREATE_JOINABLE */
2165 apr_threadattr_detach_set(thread_attr, 0);
2167 if (ap_thread_stacksize != 0) {
2168 apr_threadattr_stacksize_set(thread_attr, ap_thread_stacksize);
2171 ts->threads = threads;
2172 ts->listener = NULL;
2173 ts->child_num_arg = child_num_arg;
2174 ts->threadattr = thread_attr;
2176 rv = apr_thread_create(&start_thread_id, thread_attr, start_threads,
2178 if (rv != APR_SUCCESS) {
2179 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
2180 "apr_thread_create: unable to create worker thread");
2181 /* let the parent decide how bad this really is */
2182 clean_child_exit(APEXIT_CHILDSICK);
2185 mpm_state = AP_MPMQ_RUNNING;
2187 /* If we are only running in one_process mode, we will want to
2188 * still handle signals. */
2190 /* Block until we get a terminating signal. */
2191 apr_signal_thread(check_signal);
2192 /* make sure the start thread has finished; signal_threads()
2193 * and join_workers() depend on that
2195 /* XXX join_start_thread() won't be awakened if one of our
2196 * threads encounters a critical error and attempts to
2197 * shutdown this child
2199 join_start_thread(start_thread_id);
2201 /* helps us terminate a little more quickly than the dispatch of the
2202 * signal thread; beats the Pipe of Death and the browsers
2204 signal_threads(ST_UNGRACEFUL);
2206 /* A terminating signal was received. Now join each of the
2207 * workers to clean them up.
2208 * If the worker already exited, then the join frees
2209 * their resources and returns.
2210 * If the worker hasn't exited, then this blocks until
2211 * they have (then cleans up).
2213 join_workers(ts->listener, threads);
2215 else { /* !one_process */
2216 /* remove SIGTERM from the set of blocked signals... if one of
2217 * the other threads in the process needs to take us down
2218 * (e.g., for MaxConnectionsPerChild) it will send us SIGTERM
2220 unblock_signal(SIGTERM);
2221 apr_signal(SIGTERM, dummy_signal_handler);
2222 /* Watch for any messages from the parent over the POD */
2224 rv = ap_event_pod_check(pod);
2225 if (rv == AP_NORESTART) {
2226 /* see if termination was triggered while we slept */
2227 switch (terminate_mode) {
2236 if (rv == AP_GRACEFUL || rv == AP_RESTART) {
2237 /* make sure the start thread has finished;
2238 * signal_threads() and join_workers depend on that
2240 join_start_thread(start_thread_id);
2241 signal_threads(rv ==
2242 AP_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL);
2247 /* A terminating signal was received. Now join each of the
2248 * workers to clean them up.
2249 * If the worker already exited, then the join frees
2250 * their resources and returns.
2251 * If the worker hasn't exited, then this blocks until
2252 * they have (then cleans up).
2254 join_workers(ts->listener, threads);
2259 clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0);
2262 static int make_child(server_rec * s, int slot)
2266 if (slot + 1 > retained->max_daemons_limit) {
2267 retained->max_daemons_limit = slot + 1;
2272 event_note_child_started(slot, getpid());
2277 if ((pid = fork()) == -1) {
2278 ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
2279 "fork: Unable to fork new process");
2281 /* fork didn't succeed. There's no need to touch the scoreboard;
2282 * if we were trying to replace a failed child process, then
2283 * server_main_loop() marked its workers SERVER_DEAD, and if
2284 * we were trying to replace a child process that exited normally,
2285 * its worker_thread()s left SERVER_DEAD or SERVER_GRACEFUL behind.
2288 /* In case system resources are maxxed out, we don't want
2289 Apache running away with the CPU trying to fork over and
2290 over and over again. */
2291 apr_sleep(apr_time_from_sec(10));
2297 #ifdef HAVE_BINDPROCESSOR
2298 /* By default, AIX binds to a single processor. This bit unbinds
2299 * children which will then bind to another CPU.
2301 int status = bindprocessor(BINDPROCESS, (int) getpid(),
2302 PROCESSOR_CLASS_ANY);
2304 ap_log_error(APLOG_MARK, APLOG_DEBUG, errno,
2306 "processor unbind failed");
2308 RAISE_SIGSTOP(MAKE_CHILD);
2310 apr_signal(SIGTERM, just_die);
2315 if (ap_scoreboard_image->parent[slot].pid != 0) {
2316 /* This new child process is squatting on the scoreboard
2317 * entry owned by an exiting child process, which cannot
2318 * exit until all active requests complete.
2320 event_note_child_lost_slot(slot, pid);
2322 ap_scoreboard_image->parent[slot].quiescing = 0;
2323 ap_scoreboard_image->parent[slot].not_accepting = 0;
2324 event_note_child_started(slot, pid);
2328 /* start up a bunch of children */
2329 static void startup_children(int number_to_start)
2333 for (i = 0; number_to_start && i < ap_daemons_limit; ++i) {
2334 if (ap_scoreboard_image->parent[i].pid != 0) {
2337 if (make_child(ap_server_conf, i) < 0) {
2344 static void perform_idle_server_maintenance(void)
2347 int idle_thread_count;
2351 int totally_free_length = 0;
2352 int free_slots[MAX_SPAWN_RATE];
2355 int active_thread_count = 0;
2357 /* initialize the free_list */
2360 idle_thread_count = 0;
2364 for (i = 0; i < ap_daemons_limit; ++i) {
2365 /* Initialization to satisfy the compiler. It doesn't know
2366 * that threads_per_child is always > 0 */
2367 int status = SERVER_DEAD;
2368 int any_dying_threads = 0;
2369 int any_dead_threads = 0;
2370 int all_dead_threads = 1;
2372 if (i >= retained->max_daemons_limit
2373 && totally_free_length == retained->idle_spawn_rate)
2374 /* short cut if all active processes have been examined and
2375 * enough empty scoreboard slots have been found
2379 ps = &ap_scoreboard_image->parent[i];
2380 for (j = 0; j < threads_per_child; j++) {
2381 ws = &ap_scoreboard_image->servers[i][j];
2382 status = ws->status;
2384 /* XXX any_dying_threads is probably no longer needed GLA */
2385 any_dying_threads = any_dying_threads ||
2386 (status == SERVER_GRACEFUL);
2387 any_dead_threads = any_dead_threads || (status == SERVER_DEAD);
2388 all_dead_threads = all_dead_threads &&
2389 (status == SERVER_DEAD || status == SERVER_GRACEFUL);
2391 /* We consider a starting server as idle because we started it
2392 * at least a cycle ago, and if it still hasn't finished starting
2393 * then we're just going to swamp things worse by forking more.
2394 * So we hopefully won't need to fork more if we count it.
2395 * This depends on the ordering of SERVER_READY and SERVER_STARTING.
2397 if (ps->pid != 0) { /* XXX just set all_dead_threads in outer
2398 for loop if no pid? not much else matters */
2399 if (status <= SERVER_READY && !ps->quiescing && !ps->not_accepting
2400 && ps->generation == retained->my_generation)
2402 ++idle_thread_count;
2404 if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
2405 ++active_thread_count;
2409 if (any_dead_threads
2410 && totally_free_length < retained->idle_spawn_rate
2411 && free_length < MAX_SPAWN_RATE
2412 && (!ps->pid /* no process in the slot */
2413 || ps->quiescing)) { /* or at least one is going away */
2414 if (all_dead_threads) {
2415 /* great! we prefer these, because the new process can
2416 * start more threads sooner. So prioritize this slot
2417 * by putting it ahead of any slots with active threads.
2419 * first, make room by moving a slot that's potentially still
2420 * in use to the end of the array
2422 free_slots[free_length] = free_slots[totally_free_length];
2423 free_slots[totally_free_length++] = i;
2426 /* slot is still in use - back of the bus
2428 free_slots[free_length] = i;
2432 /* XXX if (!ps->quiescing) is probably more reliable GLA */
2433 if (!any_dying_threads) {
2439 if (retained->sick_child_detected) {
2440 if (active_thread_count > 0) {
2441 /* some child processes appear to be working. don't kill the
2444 retained->sick_child_detected = 0;
2447 /* looks like a basket case. give up.
2449 shutdown_pending = 1;
2451 ap_log_error(APLOG_MARK, APLOG_ALERT, 0,
2453 "No active workers found..."
2454 " Apache is exiting!");
2455 /* the child already logged the failure details */
2460 retained->max_daemons_limit = last_non_dead + 1;
2462 if (idle_thread_count > max_spare_threads) {
2463 /* Kill off one child */
2464 ap_event_pod_signal(pod, TRUE);
2465 retained->idle_spawn_rate = 1;
2467 else if (idle_thread_count < min_spare_threads) {
2468 /* terminate the free list */
2469 if (free_length == 0) { /* scoreboard is full, can't fork */
2471 if (active_thread_count >= ap_daemons_limit * threads_per_child) {
2472 if (!retained->maxclients_reported) {
2473 /* only report this condition once */
2474 ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
2475 "server reached MaxRequestWorkers setting, "
2476 "consider raising the MaxRequestWorkers "
2478 retained->maxclients_reported = 1;
2482 ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
2483 "scoreboard is full, not at MaxRequestWorkers");
2485 retained->idle_spawn_rate = 1;
2488 if (free_length > retained->idle_spawn_rate) {
2489 free_length = retained->idle_spawn_rate;
2491 if (retained->idle_spawn_rate >= 8) {
2492 ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
2493 "server seems busy, (you may need "
2494 "to increase StartServers, ThreadsPerChild "
2495 "or Min/MaxSpareThreads), "
2496 "spawning %d children, there are around %d idle "
2497 "threads, and %d total children", free_length,
2498 idle_thread_count, total_non_dead);
2500 for (i = 0; i < free_length; ++i) {
2501 make_child(ap_server_conf, free_slots[i]);
2503 /* the next time around we want to spawn twice as many if this
2504 * wasn't good enough, but not if we've just done a graceful
2506 if (retained->hold_off_on_exponential_spawning) {
2507 --retained->hold_off_on_exponential_spawning;
2509 else if (retained->idle_spawn_rate < MAX_SPAWN_RATE) {
2510 retained->idle_spawn_rate *= 2;
2515 retained->idle_spawn_rate = 1;
2519 static void server_main_loop(int remaining_children_to_start)
2521 ap_generation_t old_gen;
2523 apr_exit_why_e exitwhy;
2524 int status, processed_status;
2528 while (!restart_pending && !shutdown_pending) {
2529 ap_wait_or_timeout(&exitwhy, &status, &pid, pconf, ap_server_conf);
2531 if (pid.pid != -1) {
2532 processed_status = ap_process_child_status(&pid, exitwhy, status);
2533 child_slot = ap_find_child_by_pid(&pid);
2534 if (processed_status == APEXIT_CHILDFATAL) {
2535 /* fix race condition found in PR 39311
2536 * A child created at the same time as a graceful happens
2537 * can find the lock missing and create a fatal error.
2538 * It is not fatal for the last generation to be in this state.
2541 || ap_get_scoreboard_process(child_slot)->generation
2542 == retained->my_generation) {
2543 shutdown_pending = 1;
2548 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf,
2549 "Ignoring fatal error in child of previous "
2550 "generation (pid %ld).",
2552 retained->sick_child_detected = 1;
2555 else if (processed_status == APEXIT_CHILDSICK) {
2556 /* tell perform_idle_server_maintenance to check into this
2557 * on the next timer pop
2559 retained->sick_child_detected = 1;
2561 /* non-fatal death... note that it's gone in the scoreboard. */
2562 if (child_slot >= 0) {
2563 for (i = 0; i < threads_per_child; i++)
2564 ap_update_child_status_from_indexes(child_slot, i,
2566 (request_rec *) NULL);
2568 event_note_child_killed(child_slot, 0, 0);
2569 ap_scoreboard_image->parent[child_slot].quiescing = 0;
2570 if (processed_status == APEXIT_CHILDSICK) {
2571 /* resource shortage, minimize the fork rate */
2572 retained->idle_spawn_rate = 1;
2574 else if (remaining_children_to_start
2575 && child_slot < ap_daemons_limit) {
2576 /* we're still doing a 1-for-1 replacement of dead
2577 * children with new children
2579 make_child(ap_server_conf, child_slot);
2580 --remaining_children_to_start;
2583 else if (ap_unregister_extra_mpm_process(pid.pid, &old_gen) == 1) {
2585 event_note_child_killed(-1, /* already out of the scoreboard */
2587 #if APR_HAS_OTHER_CHILD
2589 else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH,
2594 else if (retained->is_graceful) {
2595 /* Great, we've probably just lost a slot in the
2596 * scoreboard. Somehow we don't know about this child.
2598 ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
2600 "long lost child came home! (pid %ld)",
2603 /* Don't perform idle maintenance when a child dies,
2604 * only do it when there's a timeout. Remember only a
2605 * finite number of children can die, and it's pretty
2606 * pathological for a lot to die suddenly.
2610 else if (remaining_children_to_start) {
2611 /* we hit a 1 second timeout in which none of the previous
2612 * generation of children needed to be reaped... so assume
2613 * they're all done, and pick up the slack if any is left.
2615 startup_children(remaining_children_to_start);
2616 remaining_children_to_start = 0;
2617 /* In any event we really shouldn't do the code below because
2618 * few of the servers we just started are in the IDLE state
2619 * yet, so we'd mistakenly create an extra server.
2624 perform_idle_server_maintenance();
2628 static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
2630 int remaining_children_to_start;
2632 ap_log_pid(pconf, ap_pid_fname);
2634 if (!retained->is_graceful) {
2635 if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
2636 mpm_state = AP_MPMQ_STOPPING;
2639 /* fix the generation number in the global score; we just got a new,
2640 * cleared scoreboard
2642 ap_scoreboard_image->global->running_generation = retained->my_generation;
2645 restart_pending = shutdown_pending = 0;
2647 /* Don't thrash... */
2648 if (max_spare_threads < min_spare_threads + threads_per_child)
2649 max_spare_threads = min_spare_threads + threads_per_child;
2651 /* If we're doing a graceful_restart then we're going to see a lot
2652 * of children exiting immediately when we get into the main loop
2653 * below (because we just sent them AP_SIG_GRACEFUL). This happens pretty
2654 * rapidly... and for each one that exits we may start a new one, until
2655 * there are at least min_spare_threads idle threads, counting across
2656 * all children. But we may be permitted to start more children than
2657 * that, so we'll just keep track of how many we're
2658 * supposed to start up without the 1 second penalty between each fork.
2660 remaining_children_to_start = ap_daemons_to_start;
2661 if (remaining_children_to_start > ap_daemons_limit) {
2662 remaining_children_to_start = ap_daemons_limit;
2664 if (!retained->is_graceful) {
2665 startup_children(remaining_children_to_start);
2666 remaining_children_to_start = 0;
2669 /* give the system some time to recover before kicking into
2670 * exponential mode */
2671 retained->hold_off_on_exponential_spawning = 10;
2674 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2675 "%s configured -- resuming normal operations",
2676 ap_get_server_description());
2677 ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
2678 "Server built: %s", ap_get_server_built());
2679 ap_log_command_line(plog, s);
2681 mpm_state = AP_MPMQ_RUNNING;
2683 server_main_loop(remaining_children_to_start);
2684 mpm_state = AP_MPMQ_STOPPING;
2686 if (shutdown_pending && !retained->is_graceful) {
2687 /* Time to shut down:
2688 * Kill child processes, tell them to call child_exit, etc...
2690 ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
2691 ap_reclaim_child_processes(1, /* Start with SIGTERM */
2692 event_note_child_killed);
2695 /* cleanup pid file on normal shutdown */
2696 ap_remove_pid(pconf, ap_pid_fname);
2697 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,
2698 ap_server_conf, "caught SIGTERM, shutting down");
2701 } else if (shutdown_pending) {
2702 /* Time to gracefully shut down:
2703 * Kill child processes, tell them to call child_exit, etc...
2705 int active_children;
2707 apr_time_t cutoff = 0;
2709 /* Close our listeners, and then ask our children to do same */
2710 ap_close_listeners();
2711 ap_event_pod_killpg(pod, ap_daemons_limit, TRUE);
2712 ap_relieve_child_processes(event_note_child_killed);
2715 /* cleanup pid file on normal shutdown */
2716 ap_remove_pid(pconf, ap_pid_fname);
2717 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2718 "caught " AP_SIG_GRACEFUL_STOP_STRING
2719 ", shutting down gracefully");
2722 if (ap_graceful_shutdown_timeout) {
2723 cutoff = apr_time_now() +
2724 apr_time_from_sec(ap_graceful_shutdown_timeout);
2727 /* Don't really exit until each child has finished */
2728 shutdown_pending = 0;
2730 /* Pause for a second */
2731 apr_sleep(apr_time_from_sec(1));
2733 /* Relieve any children which have now exited */
2734 ap_relieve_child_processes(event_note_child_killed);
2736 active_children = 0;
2737 for (index = 0; index < ap_daemons_limit; ++index) {
2738 if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == APR_SUCCESS) {
2739 active_children = 1;
2740 /* Having just one child is enough to stay around */
2744 } while (!shutdown_pending && active_children &&
2745 (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
2747 /* We might be here because we received SIGTERM, either
2748 * way, try and make sure that all of our processes are
2751 ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
2752 ap_reclaim_child_processes(1, event_note_child_killed);
2757 /* we've been told to restart */
2758 apr_signal(SIGHUP, SIG_IGN);
2761 /* not worth thinking about */
2765 /* advance to the next generation */
2766 /* XXX: we really need to make sure this new generation number isn't in
2767 * use by any of the children.
2769 ++retained->my_generation;
2770 ap_scoreboard_image->global->running_generation = retained->my_generation;
2772 if (retained->is_graceful) {
2773 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2774 AP_SIG_GRACEFUL_STRING
2775 " received. Doing graceful restart");
2776 /* wake up the children...time to die. But we'll have more soon */
2777 ap_event_pod_killpg(pod, ap_daemons_limit, TRUE);
2780 /* This is mostly for debugging... so that we know what is still
2781 * gracefully dealing with existing request.
2786 /* Kill 'em all. Since the child acts the same on the parents SIGTERM
2787 * and a SIGHUP, we may as well use the same signal, because some user
2788 * pthreads are stealing signals from us left and right.
2790 ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
2792 ap_reclaim_child_processes(1, /* Start with SIGTERM */
2793 event_note_child_killed);
2794 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2795 "SIGHUP received. Attempting to restart");
2801 /* This really should be a post_config hook, but the error log is already
2802 * redirected by that point, so we need to do this in the open_logs phase.
2804 static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
2805 apr_pool_t * ptemp, server_rec * s)
2808 int level_flags = 0;
2813 /* the reverse of pre_config, we want this only the first time around */
2814 if (retained->module_loads == 1) {
2816 level_flags |= APLOG_STARTUP;
2819 if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {
2820 ap_log_error(APLOG_MARK, APLOG_ALERT | level_flags, 0,
2821 (startup ? NULL : s),
2822 "no listening sockets available, shutting down");
2827 if ((rv = ap_event_pod_open(pconf, &pod))) {
2828 ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
2829 (startup ? NULL : s),
2830 "could not open pipe-of-death");
2837 static int event_pre_config(apr_pool_t * pconf, apr_pool_t * plog,
2840 int no_detach, debug, foreground;
2842 const char *userdata_key = "mpm_event_module";
2844 mpm_state = AP_MPMQ_STARTING;
2846 debug = ap_exists_config_define("DEBUG");
2849 foreground = one_process = 1;
2853 one_process = ap_exists_config_define("ONE_PROCESS");
2854 no_detach = ap_exists_config_define("NO_DETACH");
2855 foreground = ap_exists_config_define("FOREGROUND");
2858 /* sigh, want this only the second time around */
2859 retained = ap_retained_data_get(userdata_key);
2861 retained = ap_retained_data_create(userdata_key, sizeof(*retained));
2862 retained->max_daemons_limit = -1;
2863 retained->idle_spawn_rate = 1;
2865 ++retained->module_loads;
2866 if (retained->module_loads == 2) {
2867 rv = apr_pollset_create(&event_pollset, 1, plog,
2868 APR_POLLSET_WAKEABLE|APR_POLLSET_NOCOPY);
2869 if (rv != APR_SUCCESS) {
2870 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,
2871 "apr_pollset_create failed; check system or user limits");
2872 return HTTP_INTERNAL_SERVER_ERROR;
2874 apr_pollset_destroy(event_pollset);
2876 if (!one_process && !foreground) {
2877 /* before we detach, setup crash handlers to log to errorlog */
2878 ap_fatal_signal_setup(ap_server_conf, pconf);
2879 rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND
2880 : APR_PROC_DETACH_DAEMONIZE);
2881 if (rv != APR_SUCCESS) {
2882 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,
2883 "apr_proc_detach failed");
2884 return HTTP_INTERNAL_SERVER_ERROR;
2889 parent_pid = ap_my_pid = getpid();
2891 ap_listen_pre_config();
2892 ap_daemons_to_start = DEFAULT_START_DAEMON;
2893 min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
2894 max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
2895 server_limit = DEFAULT_SERVER_LIMIT;
2896 thread_limit = DEFAULT_THREAD_LIMIT;
2897 ap_daemons_limit = server_limit;
2898 threads_per_child = DEFAULT_THREADS_PER_CHILD;
2899 max_workers = ap_daemons_limit * threads_per_child;
2900 ap_extended_status = 0;
2905 static int event_check_config(apr_pool_t *p, apr_pool_t *plog,
2906 apr_pool_t *ptemp, server_rec *s)
2910 /* the reverse of pre_config, we want this only the first time around */
2911 if (retained->module_loads == 1) {
2915 if (server_limit > MAX_SERVER_LIMIT) {
2917 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2918 "WARNING: ServerLimit of %d exceeds compile-time "
2919 "limit of", server_limit);
2920 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2921 " %d servers, decreasing to %d.",
2922 MAX_SERVER_LIMIT, MAX_SERVER_LIMIT);
2924 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2925 "ServerLimit of %d exceeds compile-time limit "
2926 "of %d, decreasing to match",
2927 server_limit, MAX_SERVER_LIMIT);
2929 server_limit = MAX_SERVER_LIMIT;
2931 else if (server_limit < 1) {
2933 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2934 "WARNING: ServerLimit of %d not allowed, "
2935 "increasing to 1.", server_limit);
2937 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2938 "ServerLimit of %d not allowed, increasing to 1",
2944 /* you cannot change ServerLimit across a restart; ignore
2947 if (!retained->first_server_limit) {
2948 retained->first_server_limit = server_limit;
2950 else if (server_limit != retained->first_server_limit) {
2951 /* don't need a startup console version here */
2952 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2953 "changing ServerLimit to %d from original value of %d "
2954 "not allowed during restart",
2955 server_limit, retained->first_server_limit);
2956 server_limit = retained->first_server_limit;
2959 if (thread_limit > MAX_THREAD_LIMIT) {
2961 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2962 "WARNING: ThreadLimit of %d exceeds compile-time "
2963 "limit of", thread_limit);
2964 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2965 " %d threads, decreasing to %d.",
2966 MAX_THREAD_LIMIT, MAX_THREAD_LIMIT);
2968 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2969 "ThreadLimit of %d exceeds compile-time limit "
2970 "of %d, decreasing to match",
2971 thread_limit, MAX_THREAD_LIMIT);
2973 thread_limit = MAX_THREAD_LIMIT;
2975 else if (thread_limit < 1) {
2977 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2978 "WARNING: ThreadLimit of %d not allowed, "
2979 "increasing to 1.", thread_limit);
2981 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2982 "ThreadLimit of %d not allowed, increasing to 1",
2988 /* you cannot change ThreadLimit across a restart; ignore
2991 if (!retained->first_thread_limit) {
2992 retained->first_thread_limit = thread_limit;
2994 else if (thread_limit != retained->first_thread_limit) {
2995 /* don't need a startup console version here */
2996 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2997 "changing ThreadLimit to %d from original value of %d "
2998 "not allowed during restart",
2999 thread_limit, retained->first_thread_limit);
3000 thread_limit = retained->first_thread_limit;
3003 if (threads_per_child > thread_limit) {
3005 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3006 "WARNING: ThreadsPerChild of %d exceeds ThreadLimit "
3007 "of", threads_per_child);
3008 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3009 " %d threads, decreasing to %d.",
3010 thread_limit, thread_limit);
3011 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3012 " To increase, please see the ThreadLimit "
3015 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3016 "ThreadsPerChild of %d exceeds ThreadLimit "
3017 "of %d, decreasing to match",
3018 threads_per_child, thread_limit);
3020 threads_per_child = thread_limit;
3022 else if (threads_per_child < 1) {
3024 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3025 "WARNING: ThreadsPerChild of %d not allowed, "
3026 "increasing to 1.", threads_per_child);
3028 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3029 "ThreadsPerChild of %d not allowed, increasing to 1",
3032 threads_per_child = 1;
3035 if (max_workers < threads_per_child) {
3037 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3038 "WARNING: MaxRequestWorkers of %d is less than "
3039 "ThreadsPerChild of", max_workers);
3040 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3041 " %d, increasing to %d. MaxRequestWorkers must be at "
3043 threads_per_child, threads_per_child);
3044 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3045 " as the number of threads in a single server.");
3047 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3048 "MaxRequestWorkers of %d is less than ThreadsPerChild "
3049 "of %d, increasing to match",
3050 max_workers, threads_per_child);
3052 max_workers = threads_per_child;
3055 ap_daemons_limit = max_workers / threads_per_child;
3057 if (max_workers % threads_per_child) {
3058 int tmp_max_workers = ap_daemons_limit * threads_per_child;
3061 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3062 "WARNING: MaxRequestWorkers of %d is not an integer "
3063 "multiple of", max_workers);
3064 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3065 " ThreadsPerChild of %d, decreasing to nearest "
3066 "multiple %d,", threads_per_child,
3068 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3069 " for a maximum of %d servers.",
3072 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3073 "MaxRequestWorkers of %d is not an integer multiple "
3074 "of ThreadsPerChild of %d, decreasing to nearest "
3075 "multiple %d", max_workers, threads_per_child,
3078 max_workers = tmp_max_workers;
3081 if (ap_daemons_limit > server_limit) {
3083 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3084 "WARNING: MaxRequestWorkers of %d would require %d "
3085 "servers and ", max_workers, ap_daemons_limit);
3086 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3087 " would exceed ServerLimit of %d, decreasing to %d.",
3088 server_limit, server_limit * threads_per_child);
3089 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3090 " To increase, please see the ServerLimit "
3093 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3094 "MaxRequestWorkers of %d would require %d servers and "
3095 "exceed ServerLimit of %d, decreasing to %d",
3096 max_workers, ap_daemons_limit, server_limit,
3097 server_limit * threads_per_child);
3099 ap_daemons_limit = server_limit;
3102 /* ap_daemons_to_start > ap_daemons_limit checked in ap_mpm_run() */
3103 if (ap_daemons_to_start < 0) {
3105 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3106 "WARNING: StartServers of %d not allowed, "
3107 "increasing to 1.", ap_daemons_to_start);
3109 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3110 "StartServers of %d not allowed, increasing to 1",
3111 ap_daemons_to_start);
3113 ap_daemons_to_start = 1;
3116 if (min_spare_threads < 1) {
3118 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3119 "WARNING: MinSpareThreads of %d not allowed, "
3120 "increasing to 1", min_spare_threads);
3121 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3122 " to avoid almost certain server failure.");
3123 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3124 " Please read the documentation.");
3126 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3127 "MinSpareThreads of %d not allowed, increasing to 1",
3130 min_spare_threads = 1;
3133 /* max_spare_threads < min_spare_threads + threads_per_child
3134 * checked in ap_mpm_run()
3140 static void event_hooks(apr_pool_t * p)
3142 /* Our open_logs hook function must run before the core's, or stderr
3143 * will be redirected to a file, and the messages won't print to the
3146 static const char *const aszSucc[] = { "core.c", NULL };
3149 ap_hook_open_logs(event_open_logs, NULL, aszSucc, APR_HOOK_REALLY_FIRST);
3150 /* we need to set the MPM state before other pre-config hooks use MPM query
3151 * to retrieve it, so register as REALLY_FIRST
3153 ap_hook_pre_config(event_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
3154 ap_hook_check_config(event_check_config, NULL, NULL, APR_HOOK_MIDDLE);
3155 ap_hook_mpm(event_run, NULL, NULL, APR_HOOK_MIDDLE);
3156 ap_hook_mpm_query(event_query, NULL, NULL, APR_HOOK_MIDDLE);
3157 ap_hook_mpm_register_timed_callback(event_register_timed_callback, NULL, NULL,
3159 ap_hook_mpm_get_name(event_get_name, NULL, NULL, APR_HOOK_MIDDLE);
3162 static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy,
3165 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3170 ap_daemons_to_start = atoi(arg);
3174 static const char *set_min_spare_threads(cmd_parms * cmd, void *dummy,
3177 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3182 min_spare_threads = atoi(arg);
3186 static const char *set_max_spare_threads(cmd_parms * cmd, void *dummy,
3189 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3194 max_spare_threads = atoi(arg);
3198 static const char *set_max_workers(cmd_parms * cmd, void *dummy,
3201 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3205 if (!strcasecmp(cmd->cmd->name, "MaxClients")) {
3206 ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL,
3207 "MaxClients is deprecated, use MaxRequestWorkers "
3210 max_workers = atoi(arg);
3214 static const char *set_threads_per_child(cmd_parms * cmd, void *dummy,
3217 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3222 threads_per_child = atoi(arg);
3225 static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg)
3227 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3232 server_limit = atoi(arg);
3236 static const char *set_thread_limit(cmd_parms * cmd, void *dummy,
3239 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3244 thread_limit = atoi(arg);
3248 static const char *set_worker_factor(cmd_parms * cmd, void *dummy,
3253 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3258 val = strtod(arg, &endptr);
3260 return "error parsing value";
3262 worker_factor = val * WORKER_FACTOR_SCALE;
3263 if (worker_factor == 0)
3269 static const command_rec event_cmds[] = {
3271 AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
3272 "Number of child processes launched at server startup"),
3273 AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF,
3274 "Maximum number of child processes for this run of Apache"),
3275 AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF,
3276 "Minimum number of idle threads, to handle request spikes"),
3277 AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF,
3278 "Maximum number of idle threads"),
3279 AP_INIT_TAKE1("MaxClients", set_max_workers, NULL, RSRC_CONF,
3280 "Deprecated name of MaxRequestWorkers"),
3281 AP_INIT_TAKE1("MaxRequestWorkers", set_max_workers, NULL, RSRC_CONF,
3282 "Maximum number of threads alive at the same time"),
3283 AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF,
3284 "Number of threads each child creates"),
3285 AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF,
3286 "Maximum number of worker threads per child process for this "
3287 "run of Apache - Upper limit for ThreadsPerChild"),
3288 AP_INIT_TAKE1("AsyncRequestWorkerFactor", set_worker_factor, NULL, RSRC_CONF,
3289 "How many additional connects will be accepted per idle "
3291 AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND,
3295 AP_DECLARE_MODULE(mpm_event) = {
3297 NULL, /* hook to run before apache parses args */
3298 NULL, /* create per-directory config structure */
3299 NULL, /* merge per-directory config structures */
3300 NULL, /* create per-server config structure */
3301 NULL, /* merge per-server config structures */
3302 event_cmds, /* command apr_table_t */
3303 event_hooks /* register_hooks */