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);
809 apr_bucket_alloc_destroy(cs->bucket_alloc);
811 ap_push_pool(worker_queue_info, p);
814 apr_atomic_inc32(&connection_count);
815 apr_pool_cleanup_register(c->pool, NULL, decrement_connection_count, apr_pool_cleanup_null);
816 c->current_thread = thd;
820 cs->pfd.desc_type = APR_POLL_SOCKET;
821 cs->pfd.reqevents = APR_POLLIN;
822 cs->pfd.desc.s = sock;
825 cs->pfd.client_data = pt;
826 TO_QUEUE_ELEM_INIT(cs);
828 ap_update_vhost_given_ip(c);
830 rc = ap_run_pre_connection(c, sock);
831 if (rc != OK && rc != DONE) {
832 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
833 "process_socket: connection aborted");
838 * XXX If the platform does not have a usable way of bundling
839 * accept() with a socket readability check, like Win32,
840 * and there are measurable delays before the
841 * socket is readable due to the first data packet arriving,
842 * it might be better to create the cs on the listener thread
843 * with the state set to CONN_STATE_CHECK_REQUEST_LINE_READABLE
845 * FreeBSD users will want to enable the HTTP accept filter
846 * module in their kernel for the highest performance
847 * When the accept filter is active, sockets are kept in the
848 * kernel until a HTTP request is received.
850 cs->state = CONN_STATE_READ_REQUEST_LINE;
856 c->current_thread = thd;
859 if (c->clogging_input_filters && !c->aborted) {
860 /* Since we have an input filter which 'cloggs' the input stream,
861 * like mod_ssl, lets just do the normal read from input filters,
862 * like the Worker MPM does.
864 ap_run_process_connection(c);
865 if (cs->state != CONN_STATE_SUSPENDED) {
866 cs->state = CONN_STATE_LINGER;
871 if (cs->state == CONN_STATE_READ_REQUEST_LINE) {
873 ap_run_process_connection(c);
875 /* state will be updated upon return
876 * fall thru to either wait for readability/timeout or
881 cs->state = CONN_STATE_LINGER;
885 if (cs->state == CONN_STATE_WRITE_COMPLETION) {
886 ap_filter_t *output_filter = c->output_filters;
888 ap_update_child_status_from_conn(sbh, SERVER_BUSY_WRITE, c);
889 while (output_filter->next != NULL) {
890 output_filter = output_filter->next;
892 rv = output_filter->frec->filter_func.out_func(output_filter, NULL);
893 if (rv != APR_SUCCESS) {
894 ap_log_cerror(APLOG_MARK, APLOG_WARNING, rv, c,
895 "network write failure in core output filter");
896 cs->state = CONN_STATE_LINGER;
898 else if (c->data_in_output_filters) {
899 /* Still in WRITE_COMPLETION_STATE:
900 * Set a write timeout for this connection, and let the
901 * event thread poll for writeability.
903 cs->expiration_time = ap_server_conf->timeout + apr_time_now();
904 apr_thread_mutex_lock(timeout_mutex);
905 TO_QUEUE_APPEND(write_completion_q, cs);
906 apr_thread_mutex_unlock(timeout_mutex);
907 cs->pfd.reqevents = APR_POLLOUT | APR_POLLHUP | APR_POLLERR;
908 rc = apr_pollset_add(event_pollset, &cs->pfd);
911 else if (c->keepalive != AP_CONN_KEEPALIVE || c->aborted ||
913 c->cs->state = CONN_STATE_LINGER;
915 else if (c->data_in_input_filters) {
916 cs->state = CONN_STATE_READ_REQUEST_LINE;
920 cs->state = CONN_STATE_CHECK_REQUEST_LINE_READABLE;
924 if (cs->state == CONN_STATE_LINGER) {
925 if (!start_lingering_close(cs))
928 else if (cs->state == CONN_STATE_CHECK_REQUEST_LINE_READABLE) {
931 /* It greatly simplifies the logic to use a single timeout value here
932 * because the new element can just be added to the end of the list and
933 * it will stay sorted in expiration time sequence. If brand new
934 * sockets are sent to the event thread for a readability check, this
935 * will be a slight behavior change - they use the non-keepalive
936 * timeout today. With a normal client, the socket will be readable in
937 * a few milliseconds anyway.
939 cs->expiration_time = ap_server_conf->keep_alive_timeout +
941 apr_thread_mutex_lock(timeout_mutex);
942 TO_QUEUE_APPEND(keepalive_q, cs);
943 apr_thread_mutex_unlock(timeout_mutex);
945 /* Add work to pollset. */
946 cs->pfd.reqevents = APR_POLLIN;
947 rc = apr_pollset_add(event_pollset, &cs->pfd);
949 if (rc != APR_SUCCESS) {
950 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
951 "process_socket: apr_pollset_add failure");
952 AP_DEBUG_ASSERT(rc == APR_SUCCESS);
958 /* requests_this_child has gone to zero or below. See if the admin coded
959 "MaxConnectionsPerChild 0", and keep going in that case. Doing it this way
960 simplifies the hot path in worker_thread */
961 static void check_infinite_requests(void)
963 if (ap_max_requests_per_child) {
964 signal_threads(ST_GRACEFUL);
967 requests_this_child = INT_MAX; /* keep going */
971 static void close_listeners(int process_slot, int *closed) {
974 disable_listensocks(process_slot);
975 ap_close_listeners();
978 ap_scoreboard_image->parent[process_slot].quiescing = 1;
979 for (i = 0; i < threads_per_child; ++i) {
980 ap_update_child_status_from_indexes(process_slot, i,
981 SERVER_GRACEFUL, NULL);
983 /* wake up the main thread */
984 kill(ap_my_pid, SIGTERM);
988 static void unblock_signal(int sig)
992 sigemptyset(&sig_mask);
993 sigaddset(&sig_mask, sig);
994 #if defined(SIGPROCMASK_SETS_THREAD_MASK)
995 sigprocmask(SIG_UNBLOCK, &sig_mask, NULL);
997 pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL);
1001 static void dummy_signal_handler(int sig)
1003 /* XXX If specifying SIG_IGN is guaranteed to unblock a syscall,
1004 * then we don't need this goofy function.
1010 static apr_status_t s_socket_add(void *user_baton,
1014 s_baton_t *s = (s_baton_t*)user_baton;
1015 /* XXXXX: recycle listener_poll_types */
1016 listener_poll_type *pt = ap_malloc(sizeof(*pt));
1018 pt->baton = serf_baton;
1019 pfd->client_data = pt;
1020 return apr_pollset_add(s->pollset, pfd);
1023 static apr_status_t s_socket_remove(void *user_baton,
1027 s_baton_t *s = (s_baton_t*)user_baton;
1028 listener_poll_type *pt = pfd->client_data;
1030 return apr_pollset_remove(s->pollset, pfd);
1034 static apr_status_t init_pollset(apr_pool_t *p)
1037 s_baton_t *baton = NULL;
1040 listener_poll_type *pt;
1043 TO_QUEUE_INIT(write_completion_q);
1044 TO_QUEUE_INIT(keepalive_q);
1045 TO_QUEUE_INIT(linger_q);
1046 TO_QUEUE_INIT(short_linger_q);
1048 listener_pollfd = apr_palloc(p, sizeof(apr_pollfd_t) * num_listensocks);
1049 for (lr = ap_listeners; lr != NULL; lr = lr->next, i++) {
1051 AP_DEBUG_ASSERT(i < num_listensocks);
1052 pfd = &listener_pollfd[i];
1053 pt = apr_pcalloc(p, sizeof(*pt));
1054 pfd->desc_type = APR_POLL_SOCKET;
1055 pfd->desc.s = lr->sd;
1056 pfd->reqevents = APR_POLLIN;
1058 pt->type = PT_ACCEPT;
1061 pfd->client_data = pt;
1063 apr_socket_opt_set(pfd->desc.s, APR_SO_NONBLOCK, 1);
1064 apr_pollset_add(event_pollset, pfd);
1066 lr->accept_func = ap_unixd_accept;
1070 baton = apr_pcalloc(p, sizeof(*baton));
1071 baton->pollset = event_pollset;
1072 /* TODO: subpools, threads, reuse, etc. -- currently use malloc() inside :( */
1075 g_serf = serf_context_create_ex(baton,
1077 s_socket_remove, p);
1079 ap_register_provider(p, "mpm_serf",
1080 "instance", "0", g_serf);
1087 static apr_status_t push_timer2worker(timer_event_t* te)
1089 return ap_queue_push_timer(worker_queue, te);
1092 static apr_status_t push2worker(const apr_pollfd_t * pfd,
1093 apr_pollset_t * pollset)
1095 listener_poll_type *pt = (listener_poll_type *) pfd->client_data;
1096 conn_state_t *cs = (conn_state_t *) pt->baton;
1099 rc = apr_pollset_remove(pollset, pfd);
1102 * Some of the pollset backends, like KQueue or Epoll
1103 * automagically remove the FD if the socket is closed,
1104 * therefore, we can accept _SUCCESS or _NOTFOUND,
1105 * and we still want to keep going
1107 if (rc != APR_SUCCESS && !APR_STATUS_IS_NOTFOUND(rc)) {
1108 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
1109 "pollset remove failed");
1110 start_lingering_close(cs);
1114 rc = ap_queue_push(worker_queue, cs->pfd.desc.s, cs, cs->p);
1115 if (rc != APR_SUCCESS) {
1116 /* trash the connection; we couldn't queue the connected
1117 * socket to a worker
1119 apr_bucket_alloc_destroy(cs->bucket_alloc);
1120 apr_socket_close(cs->pfd.desc.s);
1121 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1122 ap_server_conf, "push2worker: ap_queue_push failed");
1123 apr_pool_clear(cs->p);
1124 ap_push_pool(worker_queue_info, cs->p);
1131 * If *have_idle_worker_p == 0, reserve a worker thread, and set
1132 * *have_idle_worker_p = 1.
1133 * If *have_idle_worker_p is already 1, will do nothing.
1134 * If blocking == 1, block if all workers are currently busy.
1135 * If no worker was available immediately, will set *all_busy to 1.
1136 * XXX: If there are no workers, we should not block immediately but
1137 * XXX: close all keep-alive connections first.
1139 static void get_worker(int *have_idle_worker_p, int blocking, int *all_busy)
1143 if (*have_idle_worker_p) {
1144 /* already reserved a worker thread - must have hit a
1145 * transient error on a previous pass
1151 rc = ap_queue_info_wait_for_idler(worker_queue_info, all_busy);
1153 rc = ap_queue_info_try_get_idler(worker_queue_info);
1155 if (rc == APR_SUCCESS) {
1156 *have_idle_worker_p = 1;
1158 else if (!blocking && rc == APR_EAGAIN) {
1161 else if (!APR_STATUS_IS_EOF(rc)) {
1162 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
1163 "ap_queue_info_wait_for_idler failed. "
1164 "Attempting to shutdown process gracefully");
1165 signal_threads(ST_GRACEFUL);
1169 /* XXXXXX: Convert to skiplist or other better data structure
1170 * (yes, this is VERY VERY VERY VERY BAD)
1173 /* Structures to reuse */
1174 static APR_RING_HEAD(timer_free_ring_t, timer_event_t) timer_free_ring;
1176 static APR_RING_HEAD(timer_ring_t, timer_event_t) timer_ring;
1178 static apr_thread_mutex_t *g_timer_ring_mtx;
1180 static apr_status_t event_register_timed_callback(apr_time_t t,
1181 ap_mpm_callback_fn_t *cbfn,
1187 /* oh yeah, and make locking smarter/fine grained. */
1188 apr_thread_mutex_lock(g_timer_ring_mtx);
1190 if (!APR_RING_EMPTY(&timer_free_ring, timer_event_t, link)) {
1191 te = APR_RING_FIRST(&timer_free_ring);
1192 APR_RING_REMOVE(te, link);
1195 /* XXXXX: lol, pool allocation without a context from any thread.Yeah. Right. MPMs Suck. */
1196 te = ap_malloc(sizeof(timer_event_t));
1197 APR_RING_ELEM_INIT(te, link);
1202 /* XXXXX: optimize */
1203 te->when = t + apr_time_now();
1205 /* Okay, insert sorted by when.. */
1206 for (ep = APR_RING_FIRST(&timer_ring);
1207 ep != APR_RING_SENTINEL(&timer_ring,
1208 timer_event_t, link);
1209 ep = APR_RING_NEXT(ep, link))
1211 if (ep->when > te->when) {
1213 APR_RING_INSERT_BEFORE(ep, te, link);
1219 APR_RING_INSERT_TAIL(&timer_ring, te, timer_event_t, link);
1222 apr_thread_mutex_unlock(g_timer_ring_mtx);
1227 static void process_lingering_close(conn_state_t *cs, const apr_pollfd_t *pfd)
1229 apr_socket_t *csd = ap_get_conn_socket(cs->c);
1230 char dummybuf[2048];
1233 struct timeout_queue *q;
1234 q = (cs->state == CONN_STATE_LINGER_SHORT) ? &short_linger_q : &linger_q;
1236 /* socket is already in non-blocking state */
1238 nbytes = sizeof(dummybuf);
1239 rv = apr_socket_recv(csd, dummybuf, &nbytes);
1240 } while (rv == APR_SUCCESS);
1242 if (!APR_STATUS_IS_EOF(rv)) {
1246 rv = apr_pollset_remove(event_pollset, pfd);
1247 AP_DEBUG_ASSERT(rv == APR_SUCCESS);
1249 rv = apr_socket_close(csd);
1250 AP_DEBUG_ASSERT(rv == APR_SUCCESS);
1252 apr_thread_mutex_lock(timeout_mutex);
1253 TO_QUEUE_REMOVE(*q, cs);
1254 apr_thread_mutex_unlock(timeout_mutex);
1255 TO_QUEUE_ELEM_INIT(cs);
1257 apr_pool_clear(cs->p);
1258 ap_push_pool(worker_queue_info, cs->p);
1261 /* call 'func' for all elements of 'q' with timeout less than 'timeout_time'.
1262 * Pre-condition: timeout_mutex must already be locked
1263 * Post-condition: timeout_mutex will be locked again
1265 static void process_timeout_queue(struct timeout_queue *q,
1266 apr_time_t timeout_time,
1267 int (*func)(conn_state_t *))
1270 conn_state_t *first, *cs, *last;
1274 AP_DEBUG_ASSERT(!APR_RING_EMPTY(&q->head, conn_state_t, timeout_list));
1276 cs = first = APR_RING_FIRST(&q->head);
1277 while (cs != APR_RING_SENTINEL(&q->head, conn_state_t, timeout_list)
1278 && cs->expiration_time < timeout_time) {
1280 cs = APR_RING_NEXT(cs, timeout_list);
1286 APR_RING_UNSPLICE(first, last, timeout_list);
1287 AP_DEBUG_ASSERT(q->count >= count);
1289 apr_thread_mutex_unlock(timeout_mutex);
1291 cs = APR_RING_NEXT(first, timeout_list);
1292 TO_QUEUE_ELEM_INIT(first);
1297 apr_thread_mutex_lock(timeout_mutex);
1300 static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy)
1305 proc_info *ti = dummy;
1306 int process_slot = ti->pid;
1307 apr_pool_t *tpool = apr_thread_pool_get(thd);
1309 apr_pool_t *ptrans; /* Pool for per-transaction stuff */
1311 int have_idle_worker = 0;
1313 const apr_pollfd_t *out_pfd;
1314 apr_int32_t num = 0;
1315 apr_interval_time_t timeout_interval;
1316 apr_time_t timeout_time = 0, now, last_log;
1317 listener_poll_type *pt;
1318 int closed = 0, listeners_disabled = 0;
1320 last_log = apr_time_now();
1323 /* the following times out events that are really close in the future
1324 * to prevent extra poll calls
1326 * current value is .1 second
1328 #define TIMEOUT_FUDGE_FACTOR 100000
1329 #define EVENT_FUDGE_FACTOR 10000
1331 rc = init_pollset(tpool);
1332 if (rc != APR_SUCCESS) {
1333 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
1334 "failed to initialize pollset, "
1335 "attempting to shutdown process gracefully");
1336 signal_threads(ST_GRACEFUL);
1340 /* Unblock the signal used to wake this thread up, and set a handler for
1343 unblock_signal(LISTENER_SIGNAL);
1344 apr_signal(LISTENER_SIGNAL, dummy_signal_handler);
1347 int workers_were_busy = 0;
1348 if (listener_may_exit) {
1349 close_listeners(process_slot, &closed);
1350 if (terminate_mode == ST_UNGRACEFUL
1351 || apr_atomic_read32(&connection_count) == 0)
1355 if (requests_this_child <= 0) {
1356 check_infinite_requests();
1359 now = apr_time_now();
1360 if (APLOGtrace6(ap_server_conf)) {
1361 /* trace log status every second */
1362 if (now - last_log > apr_time_from_msec(1000)) {
1364 apr_thread_mutex_lock(timeout_mutex);
1365 ap_log_error(APLOG_MARK, APLOG_TRACE6, 0, ap_server_conf,
1366 "connections: %d (write-completion: %d "
1367 "keep-alive: %d lingering: %d)",
1368 connection_count, write_completion_q.count,
1370 linger_q.count + short_linger_q.count);
1371 apr_thread_mutex_unlock(timeout_mutex);
1375 apr_thread_mutex_lock(g_timer_ring_mtx);
1376 if (!APR_RING_EMPTY(&timer_ring, timer_event_t, link)) {
1377 te = APR_RING_FIRST(&timer_ring);
1378 if (te->when > now) {
1379 timeout_interval = te->when - now;
1382 timeout_interval = 1;
1386 timeout_interval = apr_time_from_msec(100);
1388 apr_thread_mutex_unlock(g_timer_ring_mtx);
1391 rc = serf_context_prerun(g_serf);
1392 if (rc != APR_SUCCESS) {
1393 /* TOOD: what should do here? ugh. */
1396 rc = apr_pollset_poll(event_pollset, timeout_interval, &num, &out_pfd);
1397 if (rc != APR_SUCCESS) {
1398 if (APR_STATUS_IS_EINTR(rc)) {
1401 if (!APR_STATUS_IS_TIMEUP(rc)) {
1402 ap_log_error(APLOG_MARK, APLOG_CRIT, rc, ap_server_conf,
1403 "apr_pollset_poll failed. Attempting to "
1404 "shutdown process gracefully");
1405 signal_threads(ST_GRACEFUL);
1409 if (listener_may_exit) {
1410 close_listeners(process_slot, &closed);
1411 if (terminate_mode == ST_UNGRACEFUL
1412 || apr_atomic_read32(&connection_count) == 0)
1416 now = apr_time_now();
1417 apr_thread_mutex_lock(g_timer_ring_mtx);
1418 for (ep = APR_RING_FIRST(&timer_ring);
1419 ep != APR_RING_SENTINEL(&timer_ring,
1420 timer_event_t, link);
1421 ep = APR_RING_FIRST(&timer_ring))
1423 if (ep->when < now + EVENT_FUDGE_FACTOR) {
1424 APR_RING_REMOVE(ep, link);
1425 push_timer2worker(ep);
1431 apr_thread_mutex_unlock(g_timer_ring_mtx);
1434 pt = (listener_poll_type *) out_pfd->client_data;
1435 if (pt->type == PT_CSD) {
1436 /* one of the sockets is readable */
1437 struct timeout_queue *remove_from_q = &write_completion_q;
1439 cs = (conn_state_t *) pt->baton;
1440 switch (cs->state) {
1441 case CONN_STATE_CHECK_REQUEST_LINE_READABLE:
1442 cs->state = CONN_STATE_READ_REQUEST_LINE;
1443 remove_from_q = &keepalive_q;
1444 /* don't wait for a worker for a keepalive request */
1447 case CONN_STATE_WRITE_COMPLETION:
1448 get_worker(&have_idle_worker, blocking,
1449 &workers_were_busy);
1450 apr_thread_mutex_lock(timeout_mutex);
1451 TO_QUEUE_REMOVE(*remove_from_q, cs);
1452 apr_thread_mutex_unlock(timeout_mutex);
1453 TO_QUEUE_ELEM_INIT(cs);
1454 /* If we didn't get a worker immediately for a keep-alive
1455 * request, we close the connection, so that the client can
1456 * re-connect to a different process.
1458 if (!have_idle_worker) {
1459 start_lingering_close(cs);
1462 rc = push2worker(out_pfd, event_pollset);
1463 if (rc != APR_SUCCESS) {
1464 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1465 ap_server_conf, "push2worker failed");
1468 have_idle_worker = 0;
1471 case CONN_STATE_LINGER_NORMAL:
1472 case CONN_STATE_LINGER_SHORT:
1473 process_lingering_close(cs, out_pfd);
1476 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1478 "event_loop: unexpected state %d",
1483 else if (pt->type == PT_ACCEPT) {
1484 /* A Listener Socket is ready for an accept() */
1485 if (workers_were_busy) {
1486 if (!listeners_disabled)
1487 disable_listensocks(process_slot);
1488 listeners_disabled = 1;
1489 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1490 "All workers busy, not accepting new conns"
1493 else if (apr_atomic_read32(&connection_count) > threads_per_child
1494 + ap_queue_info_get_idlers(worker_queue_info) *
1495 worker_factor / WORKER_FACTOR_SCALE)
1497 if (!listeners_disabled)
1498 disable_listensocks(process_slot);
1499 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1500 "Too many open connections (%u), "
1501 "not accepting new conns in this process",
1502 apr_atomic_read32(&connection_count));
1503 ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
1505 ap_queue_info_get_idlers(worker_queue_info));
1506 listeners_disabled = 1;
1508 else if (listeners_disabled) {
1509 listeners_disabled = 0;
1510 enable_listensocks(process_slot);
1512 if (!listeners_disabled) {
1513 lr = (ap_listen_rec *) pt->baton;
1514 ap_pop_pool(&ptrans, worker_queue_info);
1516 if (ptrans == NULL) {
1517 /* create a new transaction pool for each accepted socket */
1518 apr_allocator_t *allocator;
1520 apr_allocator_create(&allocator);
1521 apr_allocator_max_free_set(allocator,
1523 apr_pool_create_ex(&ptrans, pconf, NULL, allocator);
1524 apr_allocator_owner_set(allocator, ptrans);
1525 if (ptrans == NULL) {
1526 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1528 "Failed to create transaction pool");
1529 signal_threads(ST_GRACEFUL);
1533 apr_pool_tag(ptrans, "transaction");
1535 get_worker(&have_idle_worker, 1, &workers_were_busy);
1536 rc = lr->accept_func(&csd, lr, ptrans);
1538 /* later we trash rv and rely on csd to indicate
1541 AP_DEBUG_ASSERT(rc == APR_SUCCESS || !csd);
1543 if (rc == APR_EGENERAL) {
1544 /* E[NM]FILE, ENOMEM, etc */
1545 resource_shortage = 1;
1546 signal_threads(ST_GRACEFUL);
1550 rc = ap_queue_push(worker_queue, csd, NULL, ptrans);
1551 if (rc != APR_SUCCESS) {
1552 /* trash the connection; we couldn't queue the connected
1553 * socket to a worker
1555 apr_socket_close(csd);
1556 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1558 "ap_queue_push failed");
1559 apr_pool_clear(ptrans);
1560 ap_push_pool(worker_queue_info, ptrans);
1563 have_idle_worker = 0;
1567 apr_pool_clear(ptrans);
1568 ap_push_pool(worker_queue_info, ptrans);
1571 } /* if:else on pt->type */
1573 else if (pt->type == PT_SERF) {
1574 /* send socket to serf. */
1575 /* XXXX: this doesn't require get_worker() */
1576 serf_event_trigger(g_serf, pt->baton, out_pfd);
1581 } /* while for processing poll */
1583 /* XXX possible optimization: stash the current time for use as
1584 * r->request_time for new requests
1586 now = apr_time_now();
1587 /* we only do this once per 0.1s (TIMEOUT_FUDGE_FACTOR) */
1588 if (now > timeout_time) {
1589 struct process_score *ps;
1590 timeout_time = now + TIMEOUT_FUDGE_FACTOR;
1592 /* handle timed out sockets */
1593 apr_thread_mutex_lock(timeout_mutex);
1595 /* Step 1: keepalive timeouts */
1596 /* If all workers are busy, we kill older keep-alive connections so that they
1597 * may connect to another process.
1599 if (workers_were_busy && keepalive_q.count) {
1600 ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
1601 "All workers are busy, will close %d keep-alive "
1604 process_timeout_queue(&keepalive_q,
1605 timeout_time + ap_server_conf->keep_alive_timeout,
1606 start_lingering_close);
1609 process_timeout_queue(&keepalive_q, timeout_time,
1610 start_lingering_close);
1612 /* Step 2: write completion timeouts */
1613 process_timeout_queue(&write_completion_q, timeout_time, start_lingering_close);
1614 /* Step 3: (normal) lingering close completion timeouts */
1615 process_timeout_queue(&linger_q, timeout_time, stop_lingering_close);
1616 /* Step 4: (short) lingering close completion timeouts */
1617 process_timeout_queue(&short_linger_q, timeout_time, stop_lingering_close);
1619 ps = ap_get_scoreboard_process(process_slot);
1620 ps->write_completion = write_completion_q.count;
1621 ps->lingering_close = linger_q.count + short_linger_q.count;
1622 ps->keep_alive = keepalive_q.count;
1623 apr_thread_mutex_unlock(timeout_mutex);
1625 ps->connections = apr_atomic_read32(&connection_count);
1626 /* XXX: should count CONN_STATE_SUSPENDED and set ps->suspended */
1628 if (listeners_disabled && !workers_were_busy &&
1629 (int)apr_atomic_read32(&connection_count) <
1630 ((int)ap_queue_info_get_idlers(worker_queue_info) - 1) *
1631 worker_factor / WORKER_FACTOR_SCALE + threads_per_child)
1633 listeners_disabled = 0;
1634 enable_listensocks(process_slot);
1637 * XXX: do we need to set some timeout that re-enables the listensocks
1638 * XXX: in case no other event occurs?
1640 } /* listener main loop */
1642 close_listeners(process_slot, &closed);
1643 ap_queue_term(worker_queue);
1645 apr_thread_exit(thd, APR_SUCCESS);
1649 /* XXX For ungraceful termination/restart, we definitely don't want to
1650 * wait for active connections to finish but we may want to wait
1651 * for idle workers to get out of the queue code and release mutexes,
1652 * since those mutexes are cleaned up pretty soon and some systems
1653 * may not react favorably (i.e., segfault) if operations are attempted
1654 * on cleaned-up mutexes.
1656 static void *APR_THREAD_FUNC worker_thread(apr_thread_t * thd, void *dummy)
1658 proc_info *ti = dummy;
1659 int process_slot = ti->pid;
1660 int thread_slot = ti->tid;
1661 apr_socket_t *csd = NULL;
1663 apr_pool_t *ptrans; /* Pool for per-transaction stuff */
1666 timer_event_t *te = NULL;
1670 ap_scoreboard_image->servers[process_slot][thread_slot].pid = ap_my_pid;
1671 ap_scoreboard_image->servers[process_slot][thread_slot].tid = apr_os_thread_current();
1672 ap_scoreboard_image->servers[process_slot][thread_slot].generation = retained->my_generation;
1673 ap_update_child_status_from_indexes(process_slot, thread_slot,
1674 SERVER_STARTING, NULL);
1676 while (!workers_may_exit) {
1678 rv = ap_queue_info_set_idle(worker_queue_info, NULL);
1679 if (rv != APR_SUCCESS) {
1680 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
1681 "ap_queue_info_set_idle failed. Attempting to "
1682 "shutdown process gracefully.");
1683 signal_threads(ST_GRACEFUL);
1689 ap_update_child_status_from_indexes(process_slot, thread_slot,
1690 dying ? SERVER_GRACEFUL : SERVER_READY, NULL);
1692 if (workers_may_exit) {
1697 rv = ap_queue_pop_something(worker_queue, &csd, &cs, &ptrans, &te);
1699 if (rv != APR_SUCCESS) {
1700 /* We get APR_EOF during a graceful shutdown once all the
1701 * connections accepted by this server process have been handled.
1703 if (APR_STATUS_IS_EOF(rv)) {
1706 /* We get APR_EINTR whenever ap_queue_pop() has been interrupted
1707 * from an explicit call to ap_queue_interrupt_all(). This allows
1708 * us to unblock threads stuck in ap_queue_pop() when a shutdown
1711 * If workers_may_exit is set and this is ungraceful termination/
1712 * restart, we are bound to get an error on some systems (e.g.,
1713 * AIX, which sanity-checks mutex operations) since the queue
1714 * may have already been cleaned up. Don't log the "error" if
1715 * workers_may_exit is set.
1717 else if (APR_STATUS_IS_EINTR(rv)) {
1720 /* We got some other error. */
1721 else if (!workers_may_exit) {
1722 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1723 "ap_queue_pop failed");
1728 te->cbfunc(te->baton);
1731 apr_thread_mutex_lock(g_timer_ring_mtx);
1732 APR_RING_INSERT_TAIL(&timer_free_ring, te, timer_event_t, link);
1733 apr_thread_mutex_unlock(g_timer_ring_mtx);
1738 worker_sockets[thread_slot] = csd;
1739 rv = process_socket(thd, ptrans, csd, cs, process_slot, thread_slot);
1741 requests_this_child--;
1743 worker_sockets[thread_slot] = NULL;
1747 ap_update_child_status_from_indexes(process_slot, thread_slot,
1748 dying ? SERVER_DEAD :
1750 (request_rec *) NULL);
1752 apr_thread_exit(thd, APR_SUCCESS);
1756 static int check_signal(int signum)
1768 static void create_listener_thread(thread_starter * ts)
1770 int my_child_num = ts->child_num_arg;
1771 apr_threadattr_t *thread_attr = ts->threadattr;
1775 my_info = (proc_info *) ap_malloc(sizeof(proc_info));
1776 my_info->pid = my_child_num;
1777 my_info->tid = -1; /* listener thread doesn't have a thread slot */
1779 rv = apr_thread_create(&ts->listener, thread_attr, listener_thread,
1781 if (rv != APR_SUCCESS) {
1782 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1783 "apr_thread_create: unable to create listener thread");
1784 /* let the parent decide how bad this really is */
1785 clean_child_exit(APEXIT_CHILDSICK);
1787 apr_os_thread_get(&listener_os_thread, ts->listener);
1790 /* XXX under some circumstances not understood, children can get stuck
1791 * in start_threads forever trying to take over slots which will
1792 * never be cleaned up; for now there is an APLOG_DEBUG message issued
1793 * every so often when this condition occurs
1795 static void *APR_THREAD_FUNC start_threads(apr_thread_t * thd, void *dummy)
1797 thread_starter *ts = dummy;
1798 apr_thread_t **threads = ts->threads;
1799 apr_threadattr_t *thread_attr = ts->threadattr;
1800 int child_num_arg = ts->child_num_arg;
1801 int my_child_num = child_num_arg;
1805 int threads_created = 0;
1806 int listener_started = 0;
1808 int prev_threads_created;
1809 int max_recycled_pools = -1;
1811 /* We must create the fd queues before we start up the listener
1812 * and worker threads. */
1813 worker_queue = apr_pcalloc(pchild, sizeof(*worker_queue));
1814 rv = ap_queue_init(worker_queue, threads_per_child, pchild);
1815 if (rv != APR_SUCCESS) {
1816 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1817 "ap_queue_init() failed");
1818 clean_child_exit(APEXIT_CHILDFATAL);
1821 if (ap_max_mem_free != APR_ALLOCATOR_MAX_FREE_UNLIMITED) {
1822 /* If we want to conserve memory, let's not keep an unlimited number of
1823 * pools & allocators.
1824 * XXX: This should probably be a separate config directive
1826 max_recycled_pools = threads_per_child * 3 / 4 ;
1828 rv = ap_queue_info_create(&worker_queue_info, pchild,
1829 threads_per_child, max_recycled_pools);
1830 if (rv != APR_SUCCESS) {
1831 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1832 "ap_queue_info_create() failed");
1833 clean_child_exit(APEXIT_CHILDFATAL);
1836 /* Create the timeout mutex and main pollset before the listener
1839 rv = apr_thread_mutex_create(&timeout_mutex, APR_THREAD_MUTEX_DEFAULT,
1841 if (rv != APR_SUCCESS) {
1842 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
1843 "creation of the timeout mutex failed.");
1844 clean_child_exit(APEXIT_CHILDFATAL);
1847 /* Create the main pollset */
1848 rv = apr_pollset_create(&event_pollset,
1849 threads_per_child, /* XXX don't we need more, to handle
1850 * connections in K-A or lingering
1853 pchild, APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY);
1854 if (rv != APR_SUCCESS) {
1855 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
1856 "apr_pollset_create with Thread Safety failed.");
1857 clean_child_exit(APEXIT_CHILDFATAL);
1860 worker_sockets = apr_pcalloc(pchild, threads_per_child
1861 * sizeof(apr_socket_t *));
1863 loops = prev_threads_created = 0;
1865 /* threads_per_child does not include the listener thread */
1866 for (i = 0; i < threads_per_child; i++) {
1868 ap_scoreboard_image->servers[child_num_arg][i].status;
1870 if (status != SERVER_GRACEFUL && status != SERVER_DEAD) {
1874 my_info = (proc_info *) ap_malloc(sizeof(proc_info));
1875 my_info->pid = my_child_num;
1879 /* We are creating threads right now */
1880 ap_update_child_status_from_indexes(my_child_num, i,
1881 SERVER_STARTING, NULL);
1882 /* We let each thread update its own scoreboard entry. This is
1883 * done because it lets us deal with tid better.
1885 rv = apr_thread_create(&threads[i], thread_attr,
1886 worker_thread, my_info, pchild);
1887 if (rv != APR_SUCCESS) {
1888 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1889 "apr_thread_create: unable to create worker thread");
1890 /* let the parent decide how bad this really is */
1891 clean_child_exit(APEXIT_CHILDSICK);
1896 /* Start the listener only when there are workers available */
1897 if (!listener_started && threads_created) {
1898 create_listener_thread(ts);
1899 listener_started = 1;
1903 if (start_thread_may_exit || threads_created == threads_per_child) {
1906 /* wait for previous generation to clean up an entry */
1907 apr_sleep(apr_time_from_sec(1));
1909 if (loops % 120 == 0) { /* every couple of minutes */
1910 if (prev_threads_created == threads_created) {
1911 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1912 "child %" APR_PID_T_FMT " isn't taking over "
1913 "slots very quickly (%d of %d)",
1914 ap_my_pid, threads_created,
1917 prev_threads_created = threads_created;
1921 /* What state should this child_main process be listed as in the
1923 * ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING,
1924 * (request_rec *) NULL);
1926 * This state should be listed separately in the scoreboard, in some kind
1927 * of process_status, not mixed in with the worker threads' status.
1928 * "life_status" is almost right, but it's in the worker's structure, and
1929 * the name could be clearer. gla
1931 apr_thread_exit(thd, APR_SUCCESS);
1935 static void join_workers(apr_thread_t * listener, apr_thread_t ** threads)
1938 apr_status_t rv, thread_rv;
1943 /* deal with a rare timing window which affects waking up the
1944 * listener thread... if the signal sent to the listener thread
1945 * is delivered between the time it verifies that the
1946 * listener_may_exit flag is clear and the time it enters a
1947 * blocking syscall, the signal didn't do any good... work around
1948 * that by sleeping briefly and sending it again
1952 while (iter < 10 && !dying) {
1953 /* listener has not stopped accepting yet */
1954 apr_sleep(apr_time_make(0, 500000));
1959 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1960 "the listener thread didn't stop accepting");
1963 rv = apr_thread_join(&thread_rv, listener);
1964 if (rv != APR_SUCCESS) {
1965 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1966 "apr_thread_join: unable to join listener thread");
1971 for (i = 0; i < threads_per_child; i++) {
1972 if (threads[i]) { /* if we ever created this thread */
1973 rv = apr_thread_join(&thread_rv, threads[i]);
1974 if (rv != APR_SUCCESS) {
1975 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1976 "apr_thread_join: unable to join worker "
1983 static void join_start_thread(apr_thread_t * start_thread_id)
1985 apr_status_t rv, thread_rv;
1987 start_thread_may_exit = 1; /* tell it to give up in case it is still
1988 * trying to take over slots from a
1989 * previous generation
1991 rv = apr_thread_join(&thread_rv, start_thread_id);
1992 if (rv != APR_SUCCESS) {
1993 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1994 "apr_thread_join: unable to join the start " "thread");
1998 static void child_main(int child_num_arg)
2000 apr_thread_t **threads;
2003 apr_threadattr_t *thread_attr;
2004 apr_thread_t *start_thread_id;
2006 mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
2009 ap_my_pid = getpid();
2010 ap_fatal_signal_child_setup(ap_server_conf);
2011 apr_pool_create(&pchild, pconf);
2013 /*stuff to do before we switch id's, so we have permissions. */
2014 ap_reopen_scoreboard(pchild, NULL, 0);
2016 if (ap_run_drop_privileges(pchild, ap_server_conf)) {
2017 clean_child_exit(APEXIT_CHILDFATAL);
2020 apr_thread_mutex_create(&g_timer_ring_mtx, APR_THREAD_MUTEX_DEFAULT, pchild);
2021 APR_RING_INIT(&timer_free_ring, timer_event_t, link);
2022 APR_RING_INIT(&timer_ring, timer_event_t, link);
2023 ap_run_child_init(pchild, ap_server_conf);
2025 /* done with init critical section */
2027 /* Just use the standard apr_setup_signal_thread to block all signals
2028 * from being received. The child processes no longer use signals for
2029 * any communication with the parent process.
2031 rv = apr_setup_signal_thread();
2032 if (rv != APR_SUCCESS) {
2033 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
2034 "Couldn't initialize signal thread");
2035 clean_child_exit(APEXIT_CHILDFATAL);
2038 if (ap_max_requests_per_child) {
2039 requests_this_child = ap_max_requests_per_child;
2042 /* coding a value of zero means infinity */
2043 requests_this_child = INT_MAX;
2046 /* Setup worker threads */
2048 /* clear the storage; we may not create all our threads immediately,
2049 * and we want a 0 entry to indicate a thread which was not created
2051 threads = ap_calloc(threads_per_child, sizeof(apr_thread_t *));
2052 ts = apr_palloc(pchild, sizeof(*ts));
2054 apr_threadattr_create(&thread_attr, pchild);
2055 /* 0 means PTHREAD_CREATE_JOINABLE */
2056 apr_threadattr_detach_set(thread_attr, 0);
2058 if (ap_thread_stacksize != 0) {
2059 apr_threadattr_stacksize_set(thread_attr, ap_thread_stacksize);
2062 ts->threads = threads;
2063 ts->listener = NULL;
2064 ts->child_num_arg = child_num_arg;
2065 ts->threadattr = thread_attr;
2067 rv = apr_thread_create(&start_thread_id, thread_attr, start_threads,
2069 if (rv != APR_SUCCESS) {
2070 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
2071 "apr_thread_create: unable to create worker thread");
2072 /* let the parent decide how bad this really is */
2073 clean_child_exit(APEXIT_CHILDSICK);
2076 mpm_state = AP_MPMQ_RUNNING;
2078 /* If we are only running in one_process mode, we will want to
2079 * still handle signals. */
2081 /* Block until we get a terminating signal. */
2082 apr_signal_thread(check_signal);
2083 /* make sure the start thread has finished; signal_threads()
2084 * and join_workers() depend on that
2086 /* XXX join_start_thread() won't be awakened if one of our
2087 * threads encounters a critical error and attempts to
2088 * shutdown this child
2090 join_start_thread(start_thread_id);
2092 /* helps us terminate a little more quickly than the dispatch of the
2093 * signal thread; beats the Pipe of Death and the browsers
2095 signal_threads(ST_UNGRACEFUL);
2097 /* A terminating signal was received. Now join each of the
2098 * workers to clean them up.
2099 * If the worker already exited, then the join frees
2100 * their resources and returns.
2101 * If the worker hasn't exited, then this blocks until
2102 * they have (then cleans up).
2104 join_workers(ts->listener, threads);
2106 else { /* !one_process */
2107 /* remove SIGTERM from the set of blocked signals... if one of
2108 * the other threads in the process needs to take us down
2109 * (e.g., for MaxConnectionsPerChild) it will send us SIGTERM
2111 unblock_signal(SIGTERM);
2112 apr_signal(SIGTERM, dummy_signal_handler);
2113 /* Watch for any messages from the parent over the POD */
2115 rv = ap_event_pod_check(pod);
2116 if (rv == AP_NORESTART) {
2117 /* see if termination was triggered while we slept */
2118 switch (terminate_mode) {
2127 if (rv == AP_GRACEFUL || rv == AP_RESTART) {
2128 /* make sure the start thread has finished;
2129 * signal_threads() and join_workers depend on that
2131 join_start_thread(start_thread_id);
2132 signal_threads(rv ==
2133 AP_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL);
2138 /* A terminating signal was received. Now join each of the
2139 * workers to clean them up.
2140 * If the worker already exited, then the join frees
2141 * their resources and returns.
2142 * If the worker hasn't exited, then this blocks until
2143 * they have (then cleans up).
2145 join_workers(ts->listener, threads);
2150 clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0);
2153 static int make_child(server_rec * s, int slot)
2157 if (slot + 1 > retained->max_daemons_limit) {
2158 retained->max_daemons_limit = slot + 1;
2163 event_note_child_started(slot, getpid());
2168 if ((pid = fork()) == -1) {
2169 ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
2170 "fork: Unable to fork new process");
2172 /* fork didn't succeed. There's no need to touch the scoreboard;
2173 * if we were trying to replace a failed child process, then
2174 * server_main_loop() marked its workers SERVER_DEAD, and if
2175 * we were trying to replace a child process that exited normally,
2176 * its worker_thread()s left SERVER_DEAD or SERVER_GRACEFUL behind.
2179 /* In case system resources are maxxed out, we don't want
2180 Apache running away with the CPU trying to fork over and
2181 over and over again. */
2182 apr_sleep(apr_time_from_sec(10));
2188 #ifdef HAVE_BINDPROCESSOR
2189 /* By default, AIX binds to a single processor. This bit unbinds
2190 * children which will then bind to another CPU.
2192 int status = bindprocessor(BINDPROCESS, (int) getpid(),
2193 PROCESSOR_CLASS_ANY);
2195 ap_log_error(APLOG_MARK, APLOG_DEBUG, errno,
2197 "processor unbind failed");
2199 RAISE_SIGSTOP(MAKE_CHILD);
2201 apr_signal(SIGTERM, just_die);
2206 if (ap_scoreboard_image->parent[slot].pid != 0) {
2207 /* This new child process is squatting on the scoreboard
2208 * entry owned by an exiting child process, which cannot
2209 * exit until all active requests complete.
2211 event_note_child_lost_slot(slot, pid);
2213 ap_scoreboard_image->parent[slot].quiescing = 0;
2214 ap_scoreboard_image->parent[slot].not_accepting = 0;
2215 event_note_child_started(slot, pid);
2219 /* start up a bunch of children */
2220 static void startup_children(int number_to_start)
2224 for (i = 0; number_to_start && i < ap_daemons_limit; ++i) {
2225 if (ap_scoreboard_image->parent[i].pid != 0) {
2228 if (make_child(ap_server_conf, i) < 0) {
2235 static void perform_idle_server_maintenance(void)
2238 int idle_thread_count;
2242 int totally_free_length = 0;
2243 int free_slots[MAX_SPAWN_RATE];
2246 int active_thread_count = 0;
2248 /* initialize the free_list */
2251 idle_thread_count = 0;
2255 for (i = 0; i < ap_daemons_limit; ++i) {
2256 /* Initialization to satisfy the compiler. It doesn't know
2257 * that threads_per_child is always > 0 */
2258 int status = SERVER_DEAD;
2259 int any_dying_threads = 0;
2260 int any_dead_threads = 0;
2261 int all_dead_threads = 1;
2263 if (i >= retained->max_daemons_limit
2264 && totally_free_length == retained->idle_spawn_rate)
2265 /* short cut if all active processes have been examined and
2266 * enough empty scoreboard slots have been found
2270 ps = &ap_scoreboard_image->parent[i];
2271 for (j = 0; j < threads_per_child; j++) {
2272 ws = &ap_scoreboard_image->servers[i][j];
2273 status = ws->status;
2275 /* XXX any_dying_threads is probably no longer needed GLA */
2276 any_dying_threads = any_dying_threads ||
2277 (status == SERVER_GRACEFUL);
2278 any_dead_threads = any_dead_threads || (status == SERVER_DEAD);
2279 all_dead_threads = all_dead_threads &&
2280 (status == SERVER_DEAD || status == SERVER_GRACEFUL);
2282 /* We consider a starting server as idle because we started it
2283 * at least a cycle ago, and if it still hasn't finished starting
2284 * then we're just going to swamp things worse by forking more.
2285 * So we hopefully won't need to fork more if we count it.
2286 * This depends on the ordering of SERVER_READY and SERVER_STARTING.
2288 if (ps->pid != 0) { /* XXX just set all_dead_threads in outer
2289 for loop if no pid? not much else matters */
2290 if (status <= SERVER_READY && !ps->quiescing && !ps->not_accepting
2291 && ps->generation == retained->my_generation)
2293 ++idle_thread_count;
2295 if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
2296 ++active_thread_count;
2300 if (any_dead_threads
2301 && totally_free_length < retained->idle_spawn_rate
2302 && free_length < MAX_SPAWN_RATE
2303 && (!ps->pid /* no process in the slot */
2304 || ps->quiescing)) { /* or at least one is going away */
2305 if (all_dead_threads) {
2306 /* great! we prefer these, because the new process can
2307 * start more threads sooner. So prioritize this slot
2308 * by putting it ahead of any slots with active threads.
2310 * first, make room by moving a slot that's potentially still
2311 * in use to the end of the array
2313 free_slots[free_length] = free_slots[totally_free_length];
2314 free_slots[totally_free_length++] = i;
2317 /* slot is still in use - back of the bus
2319 free_slots[free_length] = i;
2323 /* XXX if (!ps->quiescing) is probably more reliable GLA */
2324 if (!any_dying_threads) {
2330 if (retained->sick_child_detected) {
2331 if (active_thread_count > 0) {
2332 /* some child processes appear to be working. don't kill the
2335 retained->sick_child_detected = 0;
2338 /* looks like a basket case. give up.
2340 shutdown_pending = 1;
2342 ap_log_error(APLOG_MARK, APLOG_ALERT, 0,
2344 "No active workers found..."
2345 " Apache is exiting!");
2346 /* the child already logged the failure details */
2351 retained->max_daemons_limit = last_non_dead + 1;
2353 if (idle_thread_count > max_spare_threads) {
2354 /* Kill off one child */
2355 ap_event_pod_signal(pod, TRUE);
2356 retained->idle_spawn_rate = 1;
2358 else if (idle_thread_count < min_spare_threads) {
2359 /* terminate the free list */
2360 if (free_length == 0) { /* scoreboard is full, can't fork */
2362 if (active_thread_count >= ap_daemons_limit * threads_per_child) {
2363 if (!retained->maxclients_reported) {
2364 /* only report this condition once */
2365 ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
2366 "server reached MaxRequestWorkers setting, "
2367 "consider raising the MaxRequestWorkers "
2369 retained->maxclients_reported = 1;
2373 ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
2374 "scoreboard is full, not at MaxRequestWorkers");
2376 retained->idle_spawn_rate = 1;
2379 if (free_length > retained->idle_spawn_rate) {
2380 free_length = retained->idle_spawn_rate;
2382 if (retained->idle_spawn_rate >= 8) {
2383 ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
2384 "server seems busy, (you may need "
2385 "to increase StartServers, ThreadsPerChild "
2386 "or Min/MaxSpareThreads), "
2387 "spawning %d children, there are around %d idle "
2388 "threads, and %d total children", free_length,
2389 idle_thread_count, total_non_dead);
2391 for (i = 0; i < free_length; ++i) {
2392 make_child(ap_server_conf, free_slots[i]);
2394 /* the next time around we want to spawn twice as many if this
2395 * wasn't good enough, but not if we've just done a graceful
2397 if (retained->hold_off_on_exponential_spawning) {
2398 --retained->hold_off_on_exponential_spawning;
2400 else if (retained->idle_spawn_rate < MAX_SPAWN_RATE) {
2401 retained->idle_spawn_rate *= 2;
2406 retained->idle_spawn_rate = 1;
2410 static void server_main_loop(int remaining_children_to_start)
2412 ap_generation_t old_gen;
2414 apr_exit_why_e exitwhy;
2415 int status, processed_status;
2419 while (!restart_pending && !shutdown_pending) {
2420 ap_wait_or_timeout(&exitwhy, &status, &pid, pconf, ap_server_conf);
2422 if (pid.pid != -1) {
2423 processed_status = ap_process_child_status(&pid, exitwhy, status);
2424 if (processed_status == APEXIT_CHILDFATAL) {
2425 shutdown_pending = 1;
2429 else if (processed_status == APEXIT_CHILDSICK) {
2430 /* tell perform_idle_server_maintenance to check into this
2431 * on the next timer pop
2433 retained->sick_child_detected = 1;
2435 /* non-fatal death... note that it's gone in the scoreboard. */
2436 child_slot = ap_find_child_by_pid(&pid);
2437 if (child_slot >= 0) {
2438 for (i = 0; i < threads_per_child; i++)
2439 ap_update_child_status_from_indexes(child_slot, i,
2441 (request_rec *) NULL);
2443 event_note_child_killed(child_slot, 0, 0);
2444 ap_scoreboard_image->parent[child_slot].quiescing = 0;
2445 if (processed_status == APEXIT_CHILDSICK) {
2446 /* resource shortage, minimize the fork rate */
2447 retained->idle_spawn_rate = 1;
2449 else if (remaining_children_to_start
2450 && child_slot < ap_daemons_limit) {
2451 /* we're still doing a 1-for-1 replacement of dead
2452 * children with new children
2454 make_child(ap_server_conf, child_slot);
2455 --remaining_children_to_start;
2458 else if (ap_unregister_extra_mpm_process(pid.pid, &old_gen) == 1) {
2460 event_note_child_killed(-1, /* already out of the scoreboard */
2462 #if APR_HAS_OTHER_CHILD
2464 else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH,
2469 else if (retained->is_graceful) {
2470 /* Great, we've probably just lost a slot in the
2471 * scoreboard. Somehow we don't know about this child.
2473 ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
2475 "long lost child came home! (pid %ld)",
2478 /* Don't perform idle maintenance when a child dies,
2479 * only do it when there's a timeout. Remember only a
2480 * finite number of children can die, and it's pretty
2481 * pathological for a lot to die suddenly.
2485 else if (remaining_children_to_start) {
2486 /* we hit a 1 second timeout in which none of the previous
2487 * generation of children needed to be reaped... so assume
2488 * they're all done, and pick up the slack if any is left.
2490 startup_children(remaining_children_to_start);
2491 remaining_children_to_start = 0;
2492 /* In any event we really shouldn't do the code below because
2493 * few of the servers we just started are in the IDLE state
2494 * yet, so we'd mistakenly create an extra server.
2499 perform_idle_server_maintenance();
2503 static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
2505 int remaining_children_to_start;
2507 ap_log_pid(pconf, ap_pid_fname);
2509 if (!retained->is_graceful) {
2510 if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
2511 mpm_state = AP_MPMQ_STOPPING;
2514 /* fix the generation number in the global score; we just got a new,
2515 * cleared scoreboard
2517 ap_scoreboard_image->global->running_generation = retained->my_generation;
2520 restart_pending = shutdown_pending = 0;
2522 /* Don't thrash... */
2523 if (max_spare_threads < min_spare_threads + threads_per_child)
2524 max_spare_threads = min_spare_threads + threads_per_child;
2526 /* If we're doing a graceful_restart then we're going to see a lot
2527 * of children exiting immediately when we get into the main loop
2528 * below (because we just sent them AP_SIG_GRACEFUL). This happens pretty
2529 * rapidly... and for each one that exits we may start a new one, until
2530 * there are at least min_spare_threads idle threads, counting across
2531 * all children. But we may be permitted to start more children than
2532 * that, so we'll just keep track of how many we're
2533 * supposed to start up without the 1 second penalty between each fork.
2535 remaining_children_to_start = ap_daemons_to_start;
2536 if (remaining_children_to_start > ap_daemons_limit) {
2537 remaining_children_to_start = ap_daemons_limit;
2539 if (!retained->is_graceful) {
2540 startup_children(remaining_children_to_start);
2541 remaining_children_to_start = 0;
2544 /* give the system some time to recover before kicking into
2545 * exponential mode */
2546 retained->hold_off_on_exponential_spawning = 10;
2549 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2550 "%s configured -- resuming normal operations",
2551 ap_get_server_description());
2552 ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
2553 "Server built: %s", ap_get_server_built());
2554 ap_log_command_line(plog, s);
2556 mpm_state = AP_MPMQ_RUNNING;
2558 server_main_loop(remaining_children_to_start);
2559 mpm_state = AP_MPMQ_STOPPING;
2561 if (shutdown_pending && !retained->is_graceful) {
2562 /* Time to shut down:
2563 * Kill child processes, tell them to call child_exit, etc...
2565 ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
2566 ap_reclaim_child_processes(1, /* Start with SIGTERM */
2567 event_note_child_killed);
2570 /* cleanup pid file on normal shutdown */
2571 ap_remove_pid(pconf, ap_pid_fname);
2572 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,
2573 ap_server_conf, "caught SIGTERM, shutting down");
2576 } else if (shutdown_pending) {
2577 /* Time to gracefully shut down:
2578 * Kill child processes, tell them to call child_exit, etc...
2580 int active_children;
2582 apr_time_t cutoff = 0;
2584 /* Close our listeners, and then ask our children to do same */
2585 ap_close_listeners();
2586 ap_event_pod_killpg(pod, ap_daemons_limit, TRUE);
2587 ap_relieve_child_processes(event_note_child_killed);
2590 /* cleanup pid file on normal shutdown */
2591 ap_remove_pid(pconf, ap_pid_fname);
2592 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2593 "caught " AP_SIG_GRACEFUL_STOP_STRING
2594 ", shutting down gracefully");
2597 if (ap_graceful_shutdown_timeout) {
2598 cutoff = apr_time_now() +
2599 apr_time_from_sec(ap_graceful_shutdown_timeout);
2602 /* Don't really exit until each child has finished */
2603 shutdown_pending = 0;
2605 /* Pause for a second */
2606 apr_sleep(apr_time_from_sec(1));
2608 /* Relieve any children which have now exited */
2609 ap_relieve_child_processes(event_note_child_killed);
2611 active_children = 0;
2612 for (index = 0; index < ap_daemons_limit; ++index) {
2613 if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == APR_SUCCESS) {
2614 active_children = 1;
2615 /* Having just one child is enough to stay around */
2619 } while (!shutdown_pending && active_children &&
2620 (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
2622 /* We might be here because we received SIGTERM, either
2623 * way, try and make sure that all of our processes are
2626 ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
2627 ap_reclaim_child_processes(1, event_note_child_killed);
2632 /* we've been told to restart */
2633 apr_signal(SIGHUP, SIG_IGN);
2636 /* not worth thinking about */
2640 /* advance to the next generation */
2641 /* XXX: we really need to make sure this new generation number isn't in
2642 * use by any of the children.
2644 ++retained->my_generation;
2645 ap_scoreboard_image->global->running_generation = retained->my_generation;
2647 if (retained->is_graceful) {
2648 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2649 AP_SIG_GRACEFUL_STRING
2650 " received. Doing graceful restart");
2651 /* wake up the children...time to die. But we'll have more soon */
2652 ap_event_pod_killpg(pod, ap_daemons_limit, TRUE);
2655 /* This is mostly for debugging... so that we know what is still
2656 * gracefully dealing with existing request.
2661 /* Kill 'em all. Since the child acts the same on the parents SIGTERM
2662 * and a SIGHUP, we may as well use the same signal, because some user
2663 * pthreads are stealing signals from us left and right.
2665 ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
2667 ap_reclaim_child_processes(1, /* Start with SIGTERM */
2668 event_note_child_killed);
2669 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
2670 "SIGHUP received. Attempting to restart");
2676 /* This really should be a post_config hook, but the error log is already
2677 * redirected by that point, so we need to do this in the open_logs phase.
2679 static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
2680 apr_pool_t * ptemp, server_rec * s)
2683 int level_flags = 0;
2688 /* the reverse of pre_config, we want this only the first time around */
2689 if (retained->module_loads == 1) {
2691 level_flags |= APLOG_STARTUP;
2694 if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {
2695 ap_log_error(APLOG_MARK, APLOG_ALERT | level_flags, 0,
2696 (startup ? NULL : s),
2697 "no listening sockets available, shutting down");
2702 if ((rv = ap_event_pod_open(pconf, &pod))) {
2703 ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
2704 (startup ? NULL : s),
2705 "could not open pipe-of-death");
2712 static int event_pre_config(apr_pool_t * pconf, apr_pool_t * plog,
2715 int no_detach, debug, foreground;
2717 const char *userdata_key = "mpm_event_module";
2719 mpm_state = AP_MPMQ_STARTING;
2721 debug = ap_exists_config_define("DEBUG");
2724 foreground = one_process = 1;
2728 one_process = ap_exists_config_define("ONE_PROCESS");
2729 no_detach = ap_exists_config_define("NO_DETACH");
2730 foreground = ap_exists_config_define("FOREGROUND");
2733 /* sigh, want this only the second time around */
2734 retained = ap_retained_data_get(userdata_key);
2736 retained = ap_retained_data_create(userdata_key, sizeof(*retained));
2737 retained->max_daemons_limit = -1;
2738 retained->idle_spawn_rate = 1;
2740 ++retained->module_loads;
2741 if (retained->module_loads == 2) {
2742 rv = apr_pollset_create(&event_pollset, 1, plog,
2743 APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY);
2744 if (rv != APR_SUCCESS) {
2745 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,
2746 "Couldn't create a Thread Safe Pollset. "
2747 "Is it supported on your platform?"
2748 "Also check system or user limits!");
2749 return HTTP_INTERNAL_SERVER_ERROR;
2751 apr_pollset_destroy(event_pollset);
2753 if (!one_process && !foreground) {
2754 /* before we detach, setup crash handlers to log to errorlog */
2755 ap_fatal_signal_setup(ap_server_conf, pconf);
2756 rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND
2757 : APR_PROC_DETACH_DAEMONIZE);
2758 if (rv != APR_SUCCESS) {
2759 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,
2760 "apr_proc_detach failed");
2761 return HTTP_INTERNAL_SERVER_ERROR;
2766 parent_pid = ap_my_pid = getpid();
2768 ap_listen_pre_config();
2769 ap_daemons_to_start = DEFAULT_START_DAEMON;
2770 min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
2771 max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
2772 server_limit = DEFAULT_SERVER_LIMIT;
2773 thread_limit = DEFAULT_THREAD_LIMIT;
2774 ap_daemons_limit = server_limit;
2775 threads_per_child = DEFAULT_THREADS_PER_CHILD;
2776 max_workers = ap_daemons_limit * threads_per_child;
2777 ap_extended_status = 0;
2782 static int event_check_config(apr_pool_t *p, apr_pool_t *plog,
2783 apr_pool_t *ptemp, server_rec *s)
2787 /* the reverse of pre_config, we want this only the first time around */
2788 if (retained->module_loads == 1) {
2792 if (server_limit > MAX_SERVER_LIMIT) {
2794 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2795 "WARNING: ServerLimit of %d exceeds compile-time "
2796 "limit of", server_limit);
2797 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2798 " %d servers, decreasing to %d.",
2799 MAX_SERVER_LIMIT, MAX_SERVER_LIMIT);
2801 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2802 "ServerLimit of %d exceeds compile-time limit "
2803 "of %d, decreasing to match",
2804 server_limit, MAX_SERVER_LIMIT);
2806 server_limit = MAX_SERVER_LIMIT;
2808 else if (server_limit < 1) {
2810 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2811 "WARNING: ServerLimit of %d not allowed, "
2812 "increasing to 1.", server_limit);
2814 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2815 "ServerLimit of %d not allowed, increasing to 1",
2821 /* you cannot change ServerLimit across a restart; ignore
2824 if (!retained->first_server_limit) {
2825 retained->first_server_limit = server_limit;
2827 else if (server_limit != retained->first_server_limit) {
2828 /* don't need a startup console version here */
2829 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2830 "changing ServerLimit to %d from original value of %d "
2831 "not allowed during restart",
2832 server_limit, retained->first_server_limit);
2833 server_limit = retained->first_server_limit;
2836 if (thread_limit > MAX_THREAD_LIMIT) {
2838 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2839 "WARNING: ThreadLimit of %d exceeds compile-time "
2840 "limit of", thread_limit);
2841 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2842 " %d threads, decreasing to %d.",
2843 MAX_THREAD_LIMIT, MAX_THREAD_LIMIT);
2845 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2846 "ThreadLimit of %d exceeds compile-time limit "
2847 "of %d, decreasing to match",
2848 thread_limit, MAX_THREAD_LIMIT);
2850 thread_limit = MAX_THREAD_LIMIT;
2852 else if (thread_limit < 1) {
2854 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2855 "WARNING: ThreadLimit of %d not allowed, "
2856 "increasing to 1.", thread_limit);
2858 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2859 "ThreadLimit of %d not allowed, increasing to 1",
2865 /* you cannot change ThreadLimit across a restart; ignore
2868 if (!retained->first_thread_limit) {
2869 retained->first_thread_limit = thread_limit;
2871 else if (thread_limit != retained->first_thread_limit) {
2872 /* don't need a startup console version here */
2873 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2874 "changing ThreadLimit to %d from original value of %d "
2875 "not allowed during restart",
2876 thread_limit, retained->first_thread_limit);
2877 thread_limit = retained->first_thread_limit;
2880 if (threads_per_child > thread_limit) {
2882 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2883 "WARNING: ThreadsPerChild of %d exceeds ThreadLimit "
2884 "of", threads_per_child);
2885 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2886 " %d threads, decreasing to %d.",
2887 thread_limit, thread_limit);
2888 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2889 " To increase, please see the ThreadLimit "
2892 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2893 "ThreadsPerChild of %d exceeds ThreadLimit "
2894 "of %d, decreasing to match",
2895 threads_per_child, thread_limit);
2897 threads_per_child = thread_limit;
2899 else if (threads_per_child < 1) {
2901 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2902 "WARNING: ThreadsPerChild of %d not allowed, "
2903 "increasing to 1.", threads_per_child);
2905 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2906 "ThreadsPerChild of %d not allowed, increasing to 1",
2909 threads_per_child = 1;
2912 if (max_workers < threads_per_child) {
2914 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2915 "WARNING: MaxRequestWorkers of %d is less than "
2916 "ThreadsPerChild of", max_workers);
2917 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2918 " %d, increasing to %d. MaxRequestWorkers must be at "
2920 threads_per_child, threads_per_child);
2921 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2922 " as the number of threads in a single server.");
2924 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2925 "MaxRequestWorkers of %d is less than ThreadsPerChild "
2926 "of %d, increasing to match",
2927 max_workers, threads_per_child);
2929 max_workers = threads_per_child;
2932 ap_daemons_limit = max_workers / threads_per_child;
2934 if (max_workers % threads_per_child) {
2935 int tmp_max_workers = ap_daemons_limit * threads_per_child;
2938 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2939 "WARNING: MaxRequestWorkers of %d is not an integer "
2940 "multiple of", max_workers);
2941 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2942 " ThreadsPerChild of %d, decreasing to nearest "
2943 "multiple %d,", threads_per_child,
2945 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2946 " for a maximum of %d servers.",
2949 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2950 "MaxRequestWorkers of %d is not an integer multiple "
2951 "of ThreadsPerChild of %d, decreasing to nearest "
2952 "multiple %d", max_workers, threads_per_child,
2955 max_workers = tmp_max_workers;
2958 if (ap_daemons_limit > server_limit) {
2960 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2961 "WARNING: MaxRequestWorkers of %d would require %d "
2962 "servers and ", max_workers, ap_daemons_limit);
2963 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2964 " would exceed ServerLimit of %d, decreasing to %d.",
2965 server_limit, server_limit * threads_per_child);
2966 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2967 " To increase, please see the ServerLimit "
2970 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2971 "MaxRequestWorkers of %d would require %d servers and "
2972 "exceed ServerLimit of %d, decreasing to %d",
2973 max_workers, ap_daemons_limit, server_limit,
2974 server_limit * threads_per_child);
2976 ap_daemons_limit = server_limit;
2979 /* ap_daemons_to_start > ap_daemons_limit checked in ap_mpm_run() */
2980 if (ap_daemons_to_start < 0) {
2982 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2983 "WARNING: StartServers of %d not allowed, "
2984 "increasing to 1.", ap_daemons_to_start);
2986 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
2987 "StartServers of %d not allowed, increasing to 1",
2988 ap_daemons_to_start);
2990 ap_daemons_to_start = 1;
2993 if (min_spare_threads < 1) {
2995 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2996 "WARNING: MinSpareThreads of %d not allowed, "
2997 "increasing to 1", min_spare_threads);
2998 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
2999 " to avoid almost certain server failure.");
3000 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL,
3001 " Please read the documentation.");
3003 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
3004 "MinSpareThreads of %d not allowed, increasing to 1",
3007 min_spare_threads = 1;
3010 /* max_spare_threads < min_spare_threads + threads_per_child
3011 * checked in ap_mpm_run()
3017 static void event_hooks(apr_pool_t * p)
3019 /* Our open_logs hook function must run before the core's, or stderr
3020 * will be redirected to a file, and the messages won't print to the
3023 static const char *const aszSucc[] = { "core.c", NULL };
3026 ap_hook_open_logs(event_open_logs, NULL, aszSucc, APR_HOOK_REALLY_FIRST);
3027 /* we need to set the MPM state before other pre-config hooks use MPM query
3028 * to retrieve it, so register as REALLY_FIRST
3030 ap_hook_pre_config(event_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
3031 ap_hook_check_config(event_check_config, NULL, NULL, APR_HOOK_MIDDLE);
3032 ap_hook_mpm(event_run, NULL, NULL, APR_HOOK_MIDDLE);
3033 ap_hook_mpm_query(event_query, NULL, NULL, APR_HOOK_MIDDLE);
3034 ap_hook_mpm_register_timed_callback(event_register_timed_callback, NULL, NULL,
3036 ap_hook_mpm_get_name(event_get_name, NULL, NULL, APR_HOOK_MIDDLE);
3039 static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy,
3042 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3047 ap_daemons_to_start = atoi(arg);
3051 static const char *set_min_spare_threads(cmd_parms * cmd, void *dummy,
3054 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3059 min_spare_threads = atoi(arg);
3063 static const char *set_max_spare_threads(cmd_parms * cmd, void *dummy,
3066 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3071 max_spare_threads = atoi(arg);
3075 static const char *set_max_workers(cmd_parms * cmd, void *dummy,
3078 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3082 if (!strcasecmp(cmd->cmd->name, "MaxClients")) {
3083 ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL,
3084 "MaxClients is deprecated, use MaxRequestWorkers "
3087 max_workers = atoi(arg);
3091 static const char *set_threads_per_child(cmd_parms * cmd, void *dummy,
3094 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3099 threads_per_child = atoi(arg);
3102 static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg)
3104 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3109 server_limit = atoi(arg);
3113 static const char *set_thread_limit(cmd_parms * cmd, void *dummy,
3116 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3121 thread_limit = atoi(arg);
3125 static const char *set_worker_factor(cmd_parms * cmd, void *dummy,
3130 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3135 val = strtod(arg, &endptr);
3137 return "error parsing value";
3139 worker_factor = val * WORKER_FACTOR_SCALE;
3140 if (worker_factor == 0)
3146 static const command_rec event_cmds[] = {
3148 AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
3149 "Number of child processes launched at server startup"),
3150 AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF,
3151 "Maximum number of child processes for this run of Apache"),
3152 AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF,
3153 "Minimum number of idle threads, to handle request spikes"),
3154 AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF,
3155 "Maximum number of idle threads"),
3156 AP_INIT_TAKE1("MaxClients", set_max_workers, NULL, RSRC_CONF,
3157 "Deprecated name of MaxRequestWorkers"),
3158 AP_INIT_TAKE1("MaxRequestWorkers", set_max_workers, NULL, RSRC_CONF,
3159 "Maximum number of threads alive at the same time"),
3160 AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF,
3161 "Number of threads each child creates"),
3162 AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF,
3163 "Maximum number of worker threads per child process for this "
3164 "run of Apache - Upper limit for ThreadsPerChild"),
3165 AP_INIT_TAKE1("AsyncRequestWorkerFactor", set_worker_factor, NULL, RSRC_CONF,
3166 "How many additional connects will be accepted per idle "
3168 AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND,
3172 AP_DECLARE_MODULE(mpm_event) = {
3174 NULL, /* hook to run before apache parses args */
3175 NULL, /* create per-directory config structure */
3176 NULL, /* merge per-directory config structures */
3177 NULL, /* create per-server config structure */
3178 NULL, /* merge per-server config structures */
3179 event_cmds, /* command apr_table_t */
3180 event_hooks /* register_hooks */