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 * significant 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 Listening 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 does not perform 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"
67 #if APR_HAVE_SYS_SOCKET_H
68 #include <sys/socket.h>
70 #if APR_HAVE_SYS_WAIT_H
73 #ifdef HAVE_SYS_PROCESSOR_H
74 #include <sys/processor.h> /* for bindprocessor() */
78 #error The Event MPM requires APR threads, but they are unavailable.
81 #include "ap_config.h"
83 #include "http_main.h"
85 #include "http_config.h" /* for read_config */
86 #include "http_core.h" /* for get_remote_host */
87 #include "http_connection.h"
88 #include "http_protocol.h"
90 #include "mpm_common.h"
91 #include "ap_listen.h"
92 #include "scoreboard.h"
94 #include "mpm_default.h"
95 #include "http_vhost.h"
97 #include "apr_skiplist.h"
100 #include <limits.h> /* for INT_MAX */
103 /* Limit on the total --- clients will be locked out if more servers than
104 * this are needed. It is intended solely to keep the server from crashing
105 * when things get out of hand.
107 * We keep a hard maximum number of servers, for two reasons --- first off,
108 * in case something goes seriously wrong, we want to stop the fork bomb
109 * short of actually crashing the machine we're running on by filling some
110 * kernel table. Secondly, it keeps the size of the scoreboard file small
111 * enough that we can read the whole thing without worrying too much about
114 #ifndef DEFAULT_SERVER_LIMIT
115 #define DEFAULT_SERVER_LIMIT 16
118 /* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want
119 * some sort of compile-time limit to help catch typos.
121 #ifndef MAX_SERVER_LIMIT
122 #define MAX_SERVER_LIMIT 20000
125 /* Limit on the threads per process. Clients will be locked out if more than
128 * We keep this for one reason it keeps the size of the scoreboard file small
129 * enough that we can read the whole thing without worrying too much about
132 #ifndef DEFAULT_THREAD_LIMIT
133 #define DEFAULT_THREAD_LIMIT 64
136 /* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT. We want
137 * some sort of compile-time limit to help catch typos.
139 #ifndef MAX_THREAD_LIMIT
140 #define MAX_THREAD_LIMIT 100000
143 #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
145 #if !APR_VERSION_AT_LEAST(1,4,0)
146 #define apr_time_from_msec(x) (x * 1000)
149 #ifndef MAX_SECS_TO_LINGER
150 #define MAX_SECS_TO_LINGER 30
152 #define SECONDS_TO_LINGER 2
155 * Actual definitions of config globals
158 #ifndef DEFAULT_WORKER_FACTOR
159 #define DEFAULT_WORKER_FACTOR 2
161 #define WORKER_FACTOR_SCALE 16 /* scale factor to allow fractional values */
162 static unsigned int worker_factor = DEFAULT_WORKER_FACTOR * WORKER_FACTOR_SCALE;
163 /* AsyncRequestWorkerFactor * 16 */
165 static int threads_per_child = 0; /* ThreadsPerChild */
166 static int ap_daemons_to_start = 0; /* StartServers */
167 static int min_spare_threads = 0; /* MinSpareThreads */
168 static int max_spare_threads = 0; /* MaxSpareThreads */
169 static int active_daemons_limit = 0; /* MaxRequestWorkers / ThreadsPerChild */
170 static int active_daemons = 0; /* workers that still active, i.e. are
171 not shutting down gracefully */
172 static int max_workers = 0; /* MaxRequestWorkers */
173 static int server_limit = 0; /* ServerLimit */
174 static int thread_limit = 0; /* ThreadLimit */
175 static int had_healthy_child = 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 listener_is_wakeable = 0; /* Pollset supports APR_POLLSET_WAKEABLE */
181 static int num_listensocks = 0;
182 static apr_int32_t conns_this_child; /* MaxConnectionsPerChild, only access
183 in listener thread */
184 static apr_uint32_t connection_count = 0; /* Number of open connections */
185 static apr_uint32_t lingering_count = 0; /* Number of connections in lingering close */
186 static apr_uint32_t suspended_count = 0; /* Number of suspended connections */
187 static apr_uint32_t clogged_count = 0; /* Number of threads processing ssl conns */
188 static apr_uint32_t threads_shutdown = 0; /* Number of threads that have shutdown
189 early during graceful termination */
190 static int resource_shortage = 0;
191 static fd_queue_t *worker_queue;
192 static fd_queue_info_t *worker_queue_info;
194 static apr_thread_mutex_t *timeout_mutex;
196 module AP_MODULE_DECLARE_DATA mpm_event_module;
198 /* forward declare */
199 struct event_srv_cfg_s;
200 typedef struct event_srv_cfg_s event_srv_cfg;
202 static apr_pollfd_t *listener_pollfd;
205 * The pollset for sockets that are in any of the timeout queues. Currently
206 * we use the timeout_mutex to make sure that connections are added/removed
207 * atomically to/from both event_pollset and a timeout queue. Otherwise
208 * some confusion can happen under high load if timeout queues and pollset
210 * XXX: It should be possible to make the lock unnecessary in many or even all
213 static apr_pollset_t *event_pollset;
216 * The chain of connections to be shutdown by a worker thread (deferred),
217 * linked list updated atomically.
219 static event_conn_state_t *volatile defer_linger_chain;
221 struct event_conn_state_t {
222 /** APR_RING of expiration timeouts */
223 APR_RING_ENTRY(event_conn_state_t) timeout_list;
224 /** the time when the entry was queued */
225 apr_time_t queue_timestamp;
226 /** connection record this struct refers to */
228 /** request record (if any) this struct refers to */
230 /** server config this struct refers to */
232 /** is the current conn_rec suspended? (disassociated with
233 * a particular MPM thread; for suspend_/resume_connection
237 /** memory pool to allocate from */
239 /** bucket allocator */
240 apr_bucket_alloc_t *bucket_alloc;
241 /** poll file descriptor information */
243 /** public parts of the connection state */
245 /** chaining in defer_linger_chain */
246 struct event_conn_state_t *chain;
249 APR_RING_HEAD(timeout_head_t, event_conn_state_t);
251 struct timeout_queue {
252 struct timeout_head_t head;
253 apr_interval_time_t timeout;
254 apr_uint32_t count; /* for this queue */
255 apr_uint32_t *total; /* for all chained/related queues */
256 struct timeout_queue *next; /* chaining */
259 * Several timeout queues that use different timeouts, so that we always can
260 * simply append to the end.
261 * write_completion_q uses vhost's TimeOut
262 * keepalive_q uses vhost's KeepAliveTimeOut
263 * linger_q uses MAX_SECS_TO_LINGER
264 * short_linger_q uses SECONDS_TO_LINGER
266 static struct timeout_queue *write_completion_q,
270 static volatile apr_time_t queues_next_expiry;
272 /* Prevent extra poll/wakeup calls for timeouts close in the future (queues
273 * have the granularity of a second anyway).
274 * XXX: Wouldn't 0.5s (instead of 0.1s) be "enough"?
276 #define TIMEOUT_FUDGE_FACTOR apr_time_from_msec(100)
279 * Macros for accessing struct timeout_queue.
280 * For TO_QUEUE_APPEND and TO_QUEUE_REMOVE, timeout_mutex must be held.
282 static void TO_QUEUE_APPEND(struct timeout_queue *q, event_conn_state_t *el)
285 apr_time_t next_expiry;
287 APR_RING_INSERT_TAIL(&q->head, el, event_conn_state_t, timeout_list);
288 apr_atomic_inc32(q->total);
291 /* Cheaply update the overall queues' next expiry according to the
292 * first entry of this queue (oldest), if necessary.
294 el = APR_RING_FIRST(&q->head);
295 q_expiry = el->queue_timestamp + q->timeout;
296 next_expiry = queues_next_expiry;
297 if (!next_expiry || next_expiry > q_expiry + TIMEOUT_FUDGE_FACTOR) {
298 queues_next_expiry = q_expiry;
299 /* Unblock the poll()ing listener for it to update its timeout. */
300 if (listener_is_wakeable) {
301 apr_pollset_wakeup(event_pollset);
306 static void TO_QUEUE_REMOVE(struct timeout_queue *q, event_conn_state_t *el)
308 APR_RING_REMOVE(el, timeout_list);
309 APR_RING_ELEM_INIT(el, timeout_list);
310 apr_atomic_dec32(q->total);
314 static struct timeout_queue *TO_QUEUE_MAKE(apr_pool_t *p, apr_time_t t,
315 struct timeout_queue *ref)
317 struct timeout_queue *q;
319 q = apr_pcalloc(p, sizeof *q);
320 APR_RING_INIT(&q->head, event_conn_state_t, timeout_list);
321 q->total = (ref) ? ref->total : apr_pcalloc(p, sizeof *q->total);
327 #define TO_QUEUE_ELEM_INIT(el) \
328 APR_RING_ELEM_INIT((el), timeout_list)
330 /* The structure used to pass unique initialization info to each thread */
333 int pslot; /* process slot */
334 int tslot; /* worker slot of the thread */
337 /* Structure used to pass information to the thread responsible for
338 * creating the rest of the threads.
342 apr_thread_t **threads;
343 apr_thread_t *listener;
345 apr_threadattr_t *threadattr;
358 } listener_poll_type;
360 /* data retained by event across load/unload of the module
361 * allocated on first call to pre-config hook; located on
362 * subsequent calls to pre-config hook
364 typedef struct event_retained_data {
365 ap_unixd_mpm_retained_data *mpm;
367 int first_server_limit;
368 int first_thread_limit;
369 int sick_child_detected;
370 int maxclients_reported;
372 * The max child slot ever assigned, preserved across restarts. Necessary
373 * to deal with MaxRequestWorkers changes across AP_SIG_GRACEFUL restarts.
374 * We use this value to optimize routines that have to scan the entire
377 int max_daemons_limit;
380 * All running workers, active and shutting down, including those that
381 * may be left from before a graceful restart.
382 * Not kept up-to-date when shutdown is pending.
387 * idle_spawn_rate is the number of children that will be spawned on the
388 * next maintenance cycle if there aren't enough idle servers. It is
389 * maintained per listeners bucket, doubled up to MAX_SPAWN_RATE, and
390 * reset only when a cycle goes by without the need to spawn.
392 int *idle_spawn_rate;
393 #ifndef MAX_SPAWN_RATE
394 #define MAX_SPAWN_RATE (32)
396 int hold_off_on_exponential_spawning;
397 } event_retained_data;
398 static event_retained_data *retained;
400 typedef struct event_child_bucket {
402 ap_listen_rec *listeners;
403 } event_child_bucket;
404 static event_child_bucket *all_buckets, /* All listeners buckets */
405 *my_bucket; /* Current child bucket */
407 struct event_srv_cfg_s {
408 struct timeout_queue *wc_q,
412 #define ID_FROM_CHILD_THREAD(c, t) ((c * thread_limit) + t)
414 /* The event MPM respects a couple of runtime flags that can aid
415 * in debugging. Setting the -DNO_DETACH flag will prevent the root process
416 * from detaching from its controlling terminal. Additionally, setting
417 * the -DONE_PROCESS flag (which implies -DNO_DETACH) will get you the
418 * child_main loop running in the process which originally started up.
419 * This gives you a pretty nice debugging environment. (You'll get a SIGHUP
420 * early in standalone_main; just continue through. This is the server
421 * trying to kill off any child processes which it might have lying
422 * around --- Apache doesn't keep track of their pids, it just sends
423 * SIGHUP to the process group, ignoring it in the root process.
424 * Continue through and you'll be fine.).
427 static int one_process = 0;
430 int raise_sigstop_flags;
433 static apr_pool_t *pconf; /* Pool for config stuff */
434 static apr_pool_t *pchild; /* Pool for httpd child stuff */
436 static pid_t ap_my_pid; /* Linux getpid() doesn't work except in main
437 thread. Use this instead */
438 static pid_t parent_pid;
439 static apr_os_thread_t *listener_os_thread;
441 /* The LISTENER_SIGNAL signal will be sent from the main thread to the
442 * listener thread to wake it up for graceful termination (what a child
443 * process from an old generation does when the admin does "apachectl
444 * graceful"). This signal will be blocked in all threads of a child
445 * process except for the listener thread.
447 #define LISTENER_SIGNAL SIGHUP
449 /* An array of socket descriptors in use by each thread used to
450 * perform a non-graceful (forced) shutdown of the server.
452 static apr_socket_t **worker_sockets;
454 static void disable_listensocks(int process_slot)
457 for (i = 0; i < num_listensocks; i++) {
458 apr_pollset_remove(event_pollset, &listener_pollfd[i]);
460 ap_scoreboard_image->parent[process_slot].not_accepting = 1;
463 static void enable_listensocks(int process_slot)
466 if (listener_may_exit) {
469 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00457)
470 "Accepting new connections again: "
471 "%u active conns (%u lingering/%u clogged/%u suspended), "
473 apr_atomic_read32(&connection_count),
474 apr_atomic_read32(&lingering_count),
475 apr_atomic_read32(&clogged_count),
476 apr_atomic_read32(&suspended_count),
477 ap_queue_info_get_idlers(worker_queue_info));
478 for (i = 0; i < num_listensocks; i++)
479 apr_pollset_add(event_pollset, &listener_pollfd[i]);
481 * XXX: This is not yet optimal. If many workers suddenly become available,
482 * XXX: the parent may kill some processes off too soon.
484 ap_scoreboard_image->parent[process_slot].not_accepting = 0;
487 static void abort_socket_nonblocking(apr_socket_t *csd)
490 apr_socket_timeout_set(csd, 0);
491 #if defined(SOL_SOCKET) && defined(SO_LINGER)
492 /* This socket is over now, and we don't want to block nor linger
493 * anymore, so reset it. A normal close could still linger in the
494 * system, while RST is fast, nonblocking, and what the peer will
495 * get if it sends us further data anyway.
498 apr_os_sock_t osd = -1;
501 opt.l_linger = 0; /* zero timeout is RST */
502 apr_os_sock_get(&osd, csd);
503 setsockopt(osd, SOL_SOCKET, SO_LINGER, (void *)&opt, sizeof opt);
506 rv = apr_socket_close(csd);
507 if (rv != APR_SUCCESS) {
508 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(00468)
509 "error closing socket");
514 static void close_worker_sockets(void)
517 for (i = 0; i < threads_per_child; i++) {
518 apr_socket_t *csd = worker_sockets[i];
520 worker_sockets[i] = NULL;
521 abort_socket_nonblocking(csd);
525 event_conn_state_t *cs = defer_linger_chain;
529 if (apr_atomic_casptr((void *)&defer_linger_chain, cs->chain,
531 /* Race lost, try again */
535 abort_socket_nonblocking(cs->pfd.desc.s);
539 static void wakeup_listener(void)
541 listener_may_exit = 1;
542 if (!listener_os_thread) {
543 /* XXX there is an obscure path that this doesn't handle perfectly:
544 * right after listener thread is created but before
545 * listener_os_thread is set, the first worker thread hits an
546 * error and starts graceful termination
551 /* Unblock the listener if it's poll()ing */
552 if (listener_is_wakeable) {
553 apr_pollset_wakeup(event_pollset);
556 /* unblock the listener if it's waiting for a worker */
557 ap_queue_info_term(worker_queue_info);
560 * we should just be able to "kill(ap_my_pid, LISTENER_SIGNAL)" on all
561 * platforms and wake up the listener thread since it is the only thread
562 * with SIGHUP unblocked, but that doesn't work on Linux
564 #ifdef HAVE_PTHREAD_KILL
565 pthread_kill(*listener_os_thread, LISTENER_SIGNAL);
567 kill(ap_my_pid, LISTENER_SIGNAL);
572 #define ST_GRACEFUL 1
573 #define ST_UNGRACEFUL 2
575 static int terminate_mode = ST_INIT;
577 static void signal_threads(int mode)
579 if (terminate_mode == mode) {
582 terminate_mode = mode;
583 retained->mpm->mpm_state = AP_MPMQ_STOPPING;
585 /* in case we weren't called from the listener thread, wake up the
590 /* for ungraceful termination, let the workers exit now;
591 * for graceful termination, the listener thread will notify the
592 * workers to exit once it has stopped accepting new connections
594 if (mode == ST_UNGRACEFUL) {
595 workers_may_exit = 1;
596 ap_queue_interrupt_all(worker_queue);
597 close_worker_sockets(); /* forcefully kill all current connections */
601 static int event_query(int query_code, int *result, apr_status_t *rv)
604 switch (query_code) {
605 case AP_MPMQ_MAX_DAEMON_USED:
606 *result = retained->max_daemons_limit;
608 case AP_MPMQ_IS_THREADED:
609 *result = AP_MPMQ_STATIC;
611 case AP_MPMQ_IS_FORKED:
612 *result = AP_MPMQ_DYNAMIC;
614 case AP_MPMQ_IS_ASYNC:
617 case AP_MPMQ_HARD_LIMIT_DAEMONS:
618 *result = server_limit;
620 case AP_MPMQ_HARD_LIMIT_THREADS:
621 *result = thread_limit;
623 case AP_MPMQ_MAX_THREADS:
624 *result = threads_per_child;
626 case AP_MPMQ_MIN_SPARE_DAEMONS:
629 case AP_MPMQ_MIN_SPARE_THREADS:
630 *result = min_spare_threads;
632 case AP_MPMQ_MAX_SPARE_DAEMONS:
635 case AP_MPMQ_MAX_SPARE_THREADS:
636 *result = max_spare_threads;
638 case AP_MPMQ_MAX_REQUESTS_DAEMON:
639 *result = ap_max_requests_per_child;
641 case AP_MPMQ_MAX_DAEMONS:
642 *result = active_daemons_limit;
644 case AP_MPMQ_MPM_STATE:
645 *result = retained->mpm->mpm_state;
647 case AP_MPMQ_GENERATION:
648 *result = retained->mpm->my_generation;
657 static void event_note_child_killed(int childnum, pid_t pid, ap_generation_t gen)
659 if (childnum != -1) { /* child had a scoreboard slot? */
660 ap_run_child_status(ap_server_conf,
661 ap_scoreboard_image->parent[childnum].pid,
662 ap_scoreboard_image->parent[childnum].generation,
663 childnum, MPM_CHILD_EXITED);
664 ap_scoreboard_image->parent[childnum].pid = 0;
667 ap_run_child_status(ap_server_conf, pid, gen, -1, MPM_CHILD_EXITED);
671 static void event_note_child_started(int slot, pid_t pid)
673 ap_scoreboard_image->parent[slot].pid = pid;
674 ap_run_child_status(ap_server_conf,
675 ap_scoreboard_image->parent[slot].pid,
676 retained->mpm->my_generation, slot, MPM_CHILD_STARTED);
679 static const char *event_get_name(void)
684 /* a clean exit from a child with proper cleanup */
685 static void clean_child_exit(int code) __attribute__ ((noreturn));
686 static void clean_child_exit(int code)
688 retained->mpm->mpm_state = AP_MPMQ_STOPPING;
690 apr_pool_destroy(pchild);
694 event_note_child_killed(/* slot */ 0, 0, 0);
700 static void just_die(int sig)
705 /*****************************************************************
706 * Connection structures and accounting...
709 static int child_fatal;
711 static apr_status_t decrement_connection_count(void *cs_)
713 event_conn_state_t *cs = cs_;
714 switch (cs->pub.state) {
715 case CONN_STATE_LINGER_NORMAL:
716 case CONN_STATE_LINGER_SHORT:
717 apr_atomic_dec32(&lingering_count);
719 case CONN_STATE_SUSPENDED:
720 apr_atomic_dec32(&suspended_count);
725 /* Unblock the listener if it's waiting for connection_count = 0 */
726 if (!apr_atomic_dec32(&connection_count)
727 && listener_is_wakeable && listener_may_exit) {
728 apr_pollset_wakeup(event_pollset);
733 static void notify_suspend(event_conn_state_t *cs)
735 ap_run_suspend_connection(cs->c, cs->r);
740 static void notify_resume(event_conn_state_t *cs, ap_sb_handle_t *sbh)
744 ap_run_resume_connection(cs->c, cs->r);
748 * Close our side of the connection, flushing data to the client first.
749 * Pre-condition: cs is not in any timeout queue and not in the pollset,
750 * timeout_mutex is not locked
751 * return: 0 if connection is fully closed,
752 * 1 if connection is lingering
753 * May only be called by worker thread.
755 static int start_lingering_close_blocking(event_conn_state_t *cs)
758 struct timeout_queue *q;
759 apr_socket_t *csd = cs->pfd.desc.s;
761 if (ap_start_lingering_close(cs->c)) {
763 apr_socket_close(csd);
764 ap_push_pool(worker_queue_info, cs->p);
770 rv = apr_socket_timeout_set(csd, 0);
771 AP_DEBUG_ASSERT(rv == APR_SUCCESS);
774 apr_socket_timeout_set(csd, 0);
777 cs->queue_timestamp = apr_time_now();
779 * If some module requested a shortened waiting period, only wait for
780 * 2s (SECONDS_TO_LINGER). This is useful for mitigating certain
783 if (apr_table_get(cs->c->notes, "short-lingering-close")) {
785 cs->pub.state = CONN_STATE_LINGER_SHORT;
789 cs->pub.state = CONN_STATE_LINGER_NORMAL;
791 apr_atomic_inc32(&lingering_count);
794 cs->pfd.reqevents = (
795 cs->pub.sense == CONN_SENSE_WANT_WRITE ? APR_POLLOUT :
796 APR_POLLIN) | APR_POLLHUP | APR_POLLERR;
797 cs->pub.sense = CONN_SENSE_DEFAULT;
798 apr_thread_mutex_lock(timeout_mutex);
799 TO_QUEUE_APPEND(q, cs);
800 rv = apr_pollset_add(event_pollset, &cs->pfd);
801 if (rv != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rv)) {
802 TO_QUEUE_REMOVE(q, cs);
803 apr_thread_mutex_unlock(timeout_mutex);
804 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(03092)
805 "start_lingering_close: apr_pollset_add failure");
806 apr_socket_close(cs->pfd.desc.s);
807 ap_push_pool(worker_queue_info, cs->p);
810 apr_thread_mutex_unlock(timeout_mutex);
815 * Defer flush and close of the connection by adding it to defer_linger_chain,
816 * for a worker to grab it and do the job (should that be blocking).
817 * Pre-condition: cs is not in any timeout queue and not in the pollset,
818 * timeout_mutex is not locked
819 * return: 1 connection is alive (but aside and about to linger)
820 * May be called by listener thread.
822 static int start_lingering_close_nonblocking(event_conn_state_t *cs)
824 event_conn_state_t *chain;
826 cs->chain = chain = defer_linger_chain;
827 if (apr_atomic_casptr((void *)&defer_linger_chain, cs,
829 /* Race lost, try again */
837 * forcibly close a lingering connection after the lingering period has
839 * Pre-condition: cs is not in any timeout queue and not in the pollset
840 * return: irrelevant (need same prototype as start_lingering_close)
842 static int stop_lingering_close(event_conn_state_t *cs)
844 apr_socket_t *csd = ap_get_conn_socket(cs->c);
845 ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf,
846 "socket reached timeout in lingering-close state");
847 abort_socket_nonblocking(csd);
848 ap_push_pool(worker_queue_info, cs->p);
850 ap_queue_interrupt_one(worker_queue);
855 * This runs before any non-MPM cleanup code on the connection;
856 * if the connection is currently suspended as far as modules
857 * know, provide notification of resumption.
859 static apr_status_t ptrans_pre_cleanup(void *dummy)
861 event_conn_state_t *cs = dummy;
864 notify_resume(cs, NULL);
870 * event_pre_read_request() and event_request_cleanup() track the
871 * current r for a given connection.
873 static apr_status_t event_request_cleanup(void *dummy)
876 event_conn_state_t *cs = ap_get_module_config(c->conn_config,
883 static void event_pre_read_request(request_rec *r, conn_rec *c)
885 event_conn_state_t *cs = ap_get_module_config(c->conn_config,
889 cs->sc = ap_get_module_config(ap_server_conf->module_config,
891 apr_pool_cleanup_register(r->pool, c, event_request_cleanup,
892 apr_pool_cleanup_null);
896 * event_post_read_request() tracks the current server config for a
899 static int event_post_read_request(request_rec *r)
901 conn_rec *c = r->connection;
902 event_conn_state_t *cs = ap_get_module_config(c->conn_config,
905 /* To preserve legacy behaviour (consistent with other MPMs), use
906 * the keepalive timeout from the base server (first on this IP:port)
907 * when none is explicitly configured on this server.
909 if (r->server->keep_alive_timeout_set) {
910 cs->sc = ap_get_module_config(r->server->module_config,
914 cs->sc = ap_get_module_config(c->base_server->module_config,
921 * process one connection in the worker
923 static void process_socket(apr_thread_t *thd, apr_pool_t * p, apr_socket_t * sock,
924 event_conn_state_t * cs, int my_child_num,
928 long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num);
932 /* XXX: This will cause unbounded mem usage for long lasting connections */
933 ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num);
935 if (cs == NULL) { /* This is a new connection */
936 listener_poll_type *pt = apr_pcalloc(p, sizeof(*pt));
937 cs = apr_pcalloc(p, sizeof(event_conn_state_t));
938 cs->bucket_alloc = apr_bucket_alloc_create(p);
939 c = ap_run_create_connection(p, ap_server_conf, sock,
940 conn_id, sbh, cs->bucket_alloc);
942 ap_push_pool(worker_queue_info, p);
945 apr_atomic_inc32(&connection_count);
946 apr_pool_cleanup_register(c->pool, cs, decrement_connection_count,
947 apr_pool_cleanup_null);
948 ap_set_module_config(c->conn_config, &mpm_event_module, cs);
949 c->current_thread = thd;
953 cs->sc = ap_get_module_config(ap_server_conf->module_config,
955 cs->pfd.desc_type = APR_POLL_SOCKET;
956 cs->pfd.reqevents = APR_POLLIN;
957 cs->pfd.desc.s = sock;
960 cs->pfd.client_data = pt;
961 apr_pool_pre_cleanup_register(p, cs, ptrans_pre_cleanup);
962 TO_QUEUE_ELEM_INIT(cs);
964 ap_update_vhost_given_ip(c);
966 rc = ap_run_pre_connection(c, sock);
967 if (rc != OK && rc != DONE) {
968 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(00469)
969 "process_socket: connection aborted");
974 * XXX If the platform does not have a usable way of bundling
975 * accept() with a socket readability check, like Win32,
976 * and there are measurable delays before the
977 * socket is readable due to the first data packet arriving,
978 * it might be better to create the cs on the listener thread
979 * with the state set to CONN_STATE_CHECK_REQUEST_LINE_READABLE
981 * FreeBSD users will want to enable the HTTP accept filter
982 * module in their kernel for the highest performance
983 * When the accept filter is active, sockets are kept in the
984 * kernel until a HTTP request is received.
986 cs->pub.state = CONN_STATE_READ_REQUEST_LINE;
988 cs->pub.sense = CONN_SENSE_DEFAULT;
992 notify_resume(cs, sbh);
993 c->current_thread = thd;
994 /* Subsequent request on a conn, and thread number is part of ID */
999 if (c->aborted || cs->pub.state == CONN_STATE_LINGER) {
1000 /* do lingering close below */
1001 cs->pub.state = CONN_STATE_LINGER;
1003 else if (c->clogging_input_filters) {
1004 /* Since we have an input filter which 'clogs' the input stream,
1005 * like mod_ssl used to, lets just do the normal read from input
1006 * filters, like the Worker MPM does. Filters that need to write
1007 * where they would otherwise read, or read where they would
1008 * otherwise write, should set the sense appropriately.
1010 apr_atomic_inc32(&clogged_count);
1011 rc = ap_run_process_connection(c);
1012 apr_atomic_dec32(&clogged_count);
1017 else if (cs->pub.state == CONN_STATE_READ_REQUEST_LINE) {
1019 rc = ap_run_process_connection(c);
1025 * The process_connection hooks above should set the connection state
1026 * appropriately upon return, for event MPM to either:
1027 * - do lingering close (CONN_STATE_LINGER),
1028 * - wait for readability of the next request with respect to the keepalive
1029 * timeout (CONN_STATE_CHECK_REQUEST_LINE_READABLE),
1030 * - keep flushing the output filters stack in nonblocking mode, and then
1031 * if required wait for read/write-ability of the underlying socket with
1032 * respect to its own timeout (CONN_STATE_WRITE_COMPLETION); since write
1033 * completion at some point may require reads (e.g. SSL_ERROR_WANT_READ),
1034 * an output filter can set the sense to CONN_SENSE_WANT_READ at any time
1035 * for event MPM to do the right thing,
1036 * - suspend the connection (SUSPENDED) such that it now interracts with
1037 * the MPM through suspend/resume_connection() hooks, and/or registered
1038 * poll callbacks (PT_USER), and/or registered timed callbacks triggered
1040 * If a process_connection hook returns an error or no hook sets the state
1041 * to one of the above expected value, we forcibly close the connection w/
1042 * CONN_STATE_LINGER. This covers the cases where no process_connection
1043 * hook executes (DECLINED), or one returns OK w/o touching the state (i.e.
1044 * CONN_STATE_READ_REQUEST_LINE remains after the call) which can happen
1045 * with third-party modules not updated to work specifically with event MPM
1046 * while this was expected to do lingering close unconditionally with
1047 * worker or prefork MPMs for instance.
1049 if (rc != OK || (cs->pub.state != CONN_STATE_LINGER
1050 && cs->pub.state != CONN_STATE_WRITE_COMPLETION
1051 && cs->pub.state != CONN_STATE_CHECK_REQUEST_LINE_READABLE
1052 && cs->pub.state != CONN_STATE_SUSPENDED)) {
1053 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(10111)
1054 "process_socket: connection processing %s: closing",
1055 rc ? apr_psprintf(c->pool, "returned error %i", rc)
1056 : apr_psprintf(c->pool, "unexpected state %i",
1057 (int)cs->pub.state));
1058 cs->pub.state = CONN_STATE_LINGER;
1061 if (cs->pub.state == CONN_STATE_WRITE_COMPLETION) {
1062 ap_filter_t *output_filter = c->output_filters;
1064 ap_update_child_status(sbh, SERVER_BUSY_WRITE, NULL);
1065 while (output_filter->next != NULL) {
1066 output_filter = output_filter->next;
1068 rv = output_filter->frec->filter_func.out_func(output_filter, NULL);
1069 if (rv != APR_SUCCESS) {
1070 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(00470)
1071 "network write failure in core output filter");
1072 cs->pub.state = CONN_STATE_LINGER;
1074 else if (c->data_in_output_filters) {
1075 /* Still in WRITE_COMPLETION_STATE:
1076 * Set a write timeout for this connection, and let the
1077 * event thread poll for writeability.
1079 cs->queue_timestamp = apr_time_now();
1082 if (cs->pub.sense == CONN_SENSE_WANT_READ) {
1083 cs->pfd.reqevents = APR_POLLIN;
1086 cs->pfd.reqevents = APR_POLLOUT;
1088 /* POLLHUP/ERR are usually returned event only (ignored here), but
1089 * some pollset backends may require them in reqevents to do the
1090 * right thing, so it shouldn't hurt.
1092 cs->pfd.reqevents |= APR_POLLHUP | APR_POLLERR;
1093 cs->pub.sense = CONN_SENSE_DEFAULT;
1095 apr_thread_mutex_lock(timeout_mutex);
1096 TO_QUEUE_APPEND(cs->sc->wc_q, cs);
1097 rc = apr_pollset_add(event_pollset, &cs->pfd);
1098 if (rc != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rc)) {
1099 TO_QUEUE_REMOVE(cs->sc->wc_q, cs);
1100 apr_thread_mutex_unlock(timeout_mutex);
1101 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf, APLOGNO(03465)
1102 "process_socket: apr_pollset_add failure for "
1103 "write completion");
1104 apr_socket_close(cs->pfd.desc.s);
1105 ap_push_pool(worker_queue_info, cs->p);
1108 apr_thread_mutex_unlock(timeout_mutex);
1112 else if (c->keepalive != AP_CONN_KEEPALIVE || c->aborted ||
1113 listener_may_exit) {
1114 cs->pub.state = CONN_STATE_LINGER;
1116 else if (c->data_in_input_filters) {
1117 cs->pub.state = CONN_STATE_READ_REQUEST_LINE;
1121 cs->pub.state = CONN_STATE_CHECK_REQUEST_LINE_READABLE;
1125 if (cs->pub.state == CONN_STATE_LINGER) {
1126 start_lingering_close_blocking(cs);
1128 else if (cs->pub.state == CONN_STATE_CHECK_REQUEST_LINE_READABLE) {
1129 /* It greatly simplifies the logic to use a single timeout value per q
1130 * because the new element can just be added to the end of the list and
1131 * it will stay sorted in expiration time sequence. If brand new
1132 * sockets are sent to the event thread for a readability check, this
1133 * will be a slight behavior change - they use the non-keepalive
1134 * timeout today. With a normal client, the socket will be readable in
1135 * a few milliseconds anyway.
1137 cs->queue_timestamp = apr_time_now();
1140 /* Add work to pollset. */
1141 cs->pfd.reqevents = APR_POLLIN;
1142 apr_thread_mutex_lock(timeout_mutex);
1143 TO_QUEUE_APPEND(cs->sc->ka_q, cs);
1144 rc = apr_pollset_add(event_pollset, &cs->pfd);
1145 if (rc != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rc)) {
1146 TO_QUEUE_REMOVE(cs->sc->ka_q, cs);
1147 apr_thread_mutex_unlock(timeout_mutex);
1148 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf, APLOGNO(03093)
1149 "process_socket: apr_pollset_add failure for "
1151 apr_socket_close(cs->pfd.desc.s);
1152 ap_push_pool(worker_queue_info, cs->p);
1155 apr_thread_mutex_unlock(timeout_mutex);
1157 else if (cs->pub.state == CONN_STATE_SUSPENDED) {
1158 apr_atomic_inc32(&suspended_count);
1163 /* conns_this_child has gone to zero or below. See if the admin coded
1164 "MaxConnectionsPerChild 0", and keep going in that case. Doing it this way
1165 simplifies the hot path in worker_thread */
1166 static void check_infinite_requests(void)
1168 if (ap_max_requests_per_child) {
1169 ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
1170 "Stopping process due to MaxConnectionsPerChild");
1171 signal_threads(ST_GRACEFUL);
1175 conns_this_child = APR_INT32_MAX;
1179 static void close_listeners(int process_slot, int *closed)
1183 disable_listensocks(process_slot);
1184 ap_close_listeners_ex(my_bucket->listeners);
1187 ap_scoreboard_image->parent[process_slot].quiescing = 1;
1188 for (i = 0; i < threads_per_child; ++i) {
1189 ap_update_child_status_from_indexes(process_slot, i,
1190 SERVER_GRACEFUL, NULL);
1192 /* wake up the main thread */
1193 kill(ap_my_pid, SIGTERM);
1195 ap_free_idle_pools(worker_queue_info);
1196 ap_queue_interrupt_all(worker_queue);
1200 static void unblock_signal(int sig)
1204 sigemptyset(&sig_mask);
1205 sigaddset(&sig_mask, sig);
1206 #if defined(SIGPROCMASK_SETS_THREAD_MASK)
1207 sigprocmask(SIG_UNBLOCK, &sig_mask, NULL);
1209 pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL);
1213 static void dummy_signal_handler(int sig)
1215 /* XXX If specifying SIG_IGN is guaranteed to unblock a syscall,
1216 * then we don't need this goofy function.
1221 static apr_status_t init_pollset(apr_pool_t *p)
1224 listener_poll_type *pt;
1227 listener_pollfd = apr_palloc(p, sizeof(apr_pollfd_t) * num_listensocks);
1228 for (lr = my_bucket->listeners; lr != NULL; lr = lr->next, i++) {
1230 AP_DEBUG_ASSERT(i < num_listensocks);
1231 pfd = &listener_pollfd[i];
1232 pt = apr_pcalloc(p, sizeof(*pt));
1233 pfd->desc_type = APR_POLL_SOCKET;
1234 pfd->desc.s = lr->sd;
1235 pfd->reqevents = APR_POLLIN;
1237 pt->type = PT_ACCEPT;
1240 pfd->client_data = pt;
1242 apr_socket_opt_set(pfd->desc.s, APR_SO_NONBLOCK, 1);
1243 apr_pollset_add(event_pollset, pfd);
1245 lr->accept_func = ap_unixd_accept;
1251 static apr_status_t push_timer2worker(timer_event_t* te)
1253 return ap_queue_push_timer(worker_queue, te);
1257 * Pre-condition: cs is neither in event_pollset nor a timeout queue
1258 * this function may only be called by the listener
1260 static apr_status_t push2worker(event_conn_state_t *cs, apr_socket_t *csd,
1266 csd = cs->pfd.desc.s;
1269 rc = ap_queue_push(worker_queue, csd, cs, ptrans);
1270 if (rc != APR_SUCCESS) {
1271 ap_log_error(APLOG_MARK, APLOG_CRIT, rc, ap_server_conf, APLOGNO(00471)
1272 "push2worker: ap_queue_push failed");
1273 /* trash the connection; we couldn't queue the connected
1274 * socket to a worker
1277 abort_socket_nonblocking(csd);
1280 ap_push_pool(worker_queue_info, ptrans);
1282 signal_threads(ST_GRACEFUL);
1289 * If *have_idle_worker_p == 0, reserve a worker thread, and set
1290 * *have_idle_worker_p = 1.
1291 * If *have_idle_worker_p is already 1, will do nothing.
1292 * If blocking == 1, block if all workers are currently busy.
1293 * If no worker was available immediately, will set *all_busy to 1.
1294 * XXX: If there are no workers, we should not block immediately but
1295 * XXX: close all keep-alive connections first.
1297 static void get_worker(int *have_idle_worker_p, int blocking, int *all_busy)
1301 if (*have_idle_worker_p) {
1302 /* already reserved a worker thread - must have hit a
1303 * transient error on a previous pass
1309 rc = ap_queue_info_wait_for_idler(worker_queue_info, all_busy);
1311 rc = ap_queue_info_try_get_idler(worker_queue_info);
1313 if (rc == APR_SUCCESS || APR_STATUS_IS_EOF(rc)) {
1314 *have_idle_worker_p = 1;
1316 else if (!blocking && rc == APR_EAGAIN) {
1320 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf, APLOGNO(00472)
1321 "ap_queue_info_wait_for_idler failed. "
1322 "Attempting to shutdown process gracefully");
1323 signal_threads(ST_GRACEFUL);
1327 /* Structures to reuse */
1328 static APR_RING_HEAD(timer_free_ring_t, timer_event_t) timer_free_ring;
1330 static apr_skiplist *timer_skiplist;
1331 static volatile apr_time_t timers_next_expiry;
1333 /* Same goal as for TIMEOUT_FUDGE_FACTOR (avoid extra poll calls), but applied
1334 * to timers. Since their timeouts are custom (user defined), we can't be too
1335 * approximative here (hence using 0.01s).
1337 #define EVENT_FUDGE_FACTOR apr_time_from_msec(10)
1339 /* The following compare function is used by apr_skiplist_insert() to keep the
1340 * elements (timers) sorted and provide O(log n) complexity (this is also true
1341 * for apr_skiplist_{find,remove}(), but those are not used in MPM event where
1342 * inserted timers are not searched nor removed, but with apr_skiplist_pop()
1343 * which does use any compare function). It is meant to return 0 when a == b,
1344 * <0 when a < b, and >0 when a > b. However apr_skiplist_insert() will not
1345 * add duplicates (i.e. a == b), and apr_skiplist_add() is only available in
1346 * APR 1.6, yet multiple timers could possibly be created in the same micro-
1347 * second (duplicates with regard to apr_time_t); therefore we implement the
1348 * compare function to return +1 instead of 0 when compared timers are equal,
1349 * thus duplicates are still added after each other (in order of insertion).
1351 static int timer_comp(void *a, void *b)
1353 apr_time_t t1 = (apr_time_t) ((timer_event_t *)a)->when;
1354 apr_time_t t2 = (apr_time_t) ((timer_event_t *)b)->when;
1355 AP_DEBUG_ASSERT(t1);
1356 AP_DEBUG_ASSERT(t2);
1357 return ((t1 < t2) ? -1 : 1);
1360 static apr_thread_mutex_t *g_timer_skiplist_mtx;
1362 static apr_status_t event_register_timed_callback(apr_time_t t,
1363 ap_mpm_callback_fn_t *cbfn,
1367 /* oh yeah, and make locking smarter/fine grained. */
1368 apr_thread_mutex_lock(g_timer_skiplist_mtx);
1370 if (!APR_RING_EMPTY(&timer_free_ring, timer_event_t, link)) {
1371 te = APR_RING_FIRST(&timer_free_ring);
1372 APR_RING_REMOVE(te, link);
1375 te = apr_skiplist_alloc(timer_skiplist, sizeof(timer_event_t));
1376 APR_RING_ELEM_INIT(te, link);
1381 /* XXXXX: optimize */
1382 te->when = t + apr_time_now();
1385 apr_time_t next_expiry;
1387 /* Okay, add sorted by when.. */
1388 apr_skiplist_insert(timer_skiplist, te);
1390 /* Cheaply update the overall timers' next expiry according to
1391 * this event, if necessary.
1393 next_expiry = timers_next_expiry;
1394 if (!next_expiry || next_expiry > te->when + EVENT_FUDGE_FACTOR) {
1395 timers_next_expiry = te->when;
1396 /* Unblock the poll()ing listener for it to update its timeout. */
1397 if (listener_is_wakeable) {
1398 apr_pollset_wakeup(event_pollset);
1403 apr_thread_mutex_unlock(g_timer_skiplist_mtx);
1410 * Close socket and clean up if remote closed its end while we were in
1412 * Only to be called in the listener thread;
1413 * Pre-condition: cs is in one of the linger queues and in the pollset
1415 static void process_lingering_close(event_conn_state_t *cs, const apr_pollfd_t *pfd)
1417 apr_socket_t *csd = ap_get_conn_socket(cs->c);
1418 char dummybuf[2048];
1421 struct timeout_queue *q;
1422 q = (cs->pub.state == CONN_STATE_LINGER_SHORT) ? short_linger_q : linger_q;
1424 /* socket is already in non-blocking state */
1426 nbytes = sizeof(dummybuf);
1427 rv = apr_socket_recv(csd, dummybuf, &nbytes);
1428 } while (rv == APR_SUCCESS);
1430 if (APR_STATUS_IS_EAGAIN(rv)) {
1434 apr_thread_mutex_lock(timeout_mutex);
1435 TO_QUEUE_REMOVE(q, cs);
1436 rv = apr_pollset_remove(event_pollset, pfd);
1437 apr_thread_mutex_unlock(timeout_mutex);
1438 AP_DEBUG_ASSERT(rv == APR_SUCCESS || APR_STATUS_IS_NOTFOUND(rv));
1440 rv = apr_socket_close(csd);
1441 AP_DEBUG_ASSERT(rv == APR_SUCCESS);
1443 ap_push_pool(worker_queue_info, cs->p);
1445 ap_queue_interrupt_one(worker_queue);
1448 /* call 'func' for all elements of 'q' with timeout less than 'timeout_time'.
1449 * Pre-condition: timeout_mutex must already be locked
1450 * Post-condition: timeout_mutex will be locked again
1452 static void process_timeout_queue(struct timeout_queue *q,
1453 apr_time_t timeout_time,
1454 int (*func)(event_conn_state_t *))
1456 apr_uint32_t total = 0, count;
1457 event_conn_state_t *first, *cs, *last;
1458 struct timeout_head_t trash;
1459 struct timeout_queue *qp;
1462 if (!apr_atomic_read32(q->total)) {
1466 APR_RING_INIT(&trash, event_conn_state_t, timeout_list);
1467 for (qp = q; qp; qp = qp->next) {
1469 cs = first = last = APR_RING_FIRST(&qp->head);
1470 while (cs != APR_RING_SENTINEL(&qp->head, event_conn_state_t,
1472 /* Trash the entry if:
1473 * - no timeout_time was given (asked for all), or
1474 * - it expired (according to the queue timeout), or
1475 * - the system clock skewed in the past: no entry should be
1476 * registered above the given timeout_time (~now) + the queue
1477 * timeout, we won't keep any here (eg. for centuries).
1479 * Otherwise stop, no following entry will match thanks to the
1480 * single timeout per queue (entries are added to the end!).
1481 * This allows maintenance in O(1).
1484 && cs->queue_timestamp + qp->timeout > timeout_time
1485 && cs->queue_timestamp < timeout_time + qp->timeout) {
1486 /* Since this is the next expiring of this queue, update the
1487 * overall queues' next expiry if it's later than this one.
1489 apr_time_t q_expiry = cs->queue_timestamp + qp->timeout;
1490 apr_time_t next_expiry = queues_next_expiry;
1491 if (!next_expiry || next_expiry > q_expiry) {
1492 queues_next_expiry = q_expiry;
1498 rv = apr_pollset_remove(event_pollset, &cs->pfd);
1499 if (rv != APR_SUCCESS && !APR_STATUS_IS_NOTFOUND(rv)) {
1500 ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, cs->c, APLOGNO(00473)
1501 "apr_pollset_remove failed");
1503 cs = APR_RING_NEXT(cs, timeout_list);
1509 APR_RING_UNSPLICE(first, last, timeout_list);
1510 APR_RING_SPLICE_TAIL(&trash, first, last, event_conn_state_t,
1512 AP_DEBUG_ASSERT(apr_atomic_read32(q->total) >= count);
1513 apr_atomic_sub32(q->total, count);
1520 apr_thread_mutex_unlock(timeout_mutex);
1521 first = APR_RING_FIRST(&trash);
1523 cs = APR_RING_NEXT(first, timeout_list);
1524 TO_QUEUE_ELEM_INIT(first);
1528 apr_thread_mutex_lock(timeout_mutex);
1531 static void process_keepalive_queue(apr_time_t timeout_time)
1533 /* If all workers are busy, we kill older keep-alive connections so
1534 * that they may connect to another process.
1536 if (!timeout_time) {
1537 ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
1538 "All workers are busy or dying, will close %u "
1539 "keep-alive connections",
1540 apr_atomic_read32(keepalive_q->total));
1542 process_timeout_queue(keepalive_q, timeout_time,
1543 start_lingering_close_nonblocking);
1546 static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy)
1550 proc_info *ti = dummy;
1551 int process_slot = ti->pslot;
1552 struct process_score *ps = ap_get_scoreboard_process(process_slot);
1553 apr_pool_t *tpool = apr_thread_pool_get(thd);
1555 apr_pool_t *ptrans; /* Pool for per-transaction stuff */
1557 int have_idle_worker = 0;
1558 const apr_pollfd_t *out_pfd;
1559 apr_int32_t num = 0;
1560 apr_interval_time_t timeout_interval;
1561 apr_time_t timeout_time = 0, now, last_log;
1562 listener_poll_type *pt;
1563 int closed = 0, listeners_disabled = 0;
1565 last_log = apr_time_now();
1568 rc = init_pollset(tpool);
1569 if (rc != APR_SUCCESS) {
1570 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
1571 "failed to initialize pollset, "
1572 "attempting to shutdown process gracefully");
1573 signal_threads(ST_GRACEFUL);
1577 /* Unblock the signal used to wake this thread up, and set a handler for
1580 unblock_signal(LISTENER_SIGNAL);
1581 apr_signal(LISTENER_SIGNAL, dummy_signal_handler);
1584 int workers_were_busy = 0;
1586 if (listener_may_exit) {
1587 close_listeners(process_slot, &closed);
1588 if (terminate_mode == ST_UNGRACEFUL
1589 || apr_atomic_read32(&connection_count) == 0)
1593 if (conns_this_child <= 0)
1594 check_infinite_requests();
1596 now = apr_time_now();
1597 if (APLOGtrace6(ap_server_conf)) {
1598 /* trace log status every second */
1599 if (now - last_log > apr_time_from_sec(1)) {
1601 apr_thread_mutex_lock(timeout_mutex);
1602 ap_log_error(APLOG_MARK, APLOG_TRACE6, 0, ap_server_conf,
1603 "connections: %u (clogged: %u write-completion: %d "
1604 "keep-alive: %d lingering: %d suspended: %u)",
1605 apr_atomic_read32(&connection_count),
1606 apr_atomic_read32(&clogged_count),
1607 apr_atomic_read32(write_completion_q->total),
1608 apr_atomic_read32(keepalive_q->total),
1609 apr_atomic_read32(&lingering_count),
1610 apr_atomic_read32(&suspended_count));
1612 ap_log_error(APLOG_MARK, APLOG_TRACE6, 0, ap_server_conf,
1613 "%u/%u workers shutdown",
1614 apr_atomic_read32(&threads_shutdown),
1617 apr_thread_mutex_unlock(timeout_mutex);
1621 /* Start with an infinite poll() timeout and update it according to
1622 * the next expiring timer or queue entry. If there are none, either
1623 * the listener is wakeable and it can poll() indefinitely until a wake
1624 * up occurs, otherwise periodic checks (maintenance, shutdown, ...)
1625 * must be performed.
1627 timeout_interval = -1;
1629 /* Push expired timers to a worker, the first remaining one determines
1630 * the maximum time to poll() below, if any.
1632 timeout_time = timers_next_expiry;
1633 if (timeout_time && timeout_time < now + EVENT_FUDGE_FACTOR) {
1634 apr_thread_mutex_lock(g_timer_skiplist_mtx);
1635 while ((te = apr_skiplist_peek(timer_skiplist))) {
1636 if (te->when > now + EVENT_FUDGE_FACTOR) {
1637 timers_next_expiry = te->when;
1638 timeout_interval = te->when - now;
1641 apr_skiplist_pop(timer_skiplist, NULL);
1642 push_timer2worker(te);
1645 timers_next_expiry = 0;
1647 apr_thread_mutex_unlock(g_timer_skiplist_mtx);
1650 /* Same for queues, use their next expiry, if any. */
1651 timeout_time = queues_next_expiry;
1653 && (timeout_interval < 0
1654 || timeout_time <= now
1655 || timeout_interval > timeout_time - now)) {
1656 timeout_interval = timeout_time > now ? timeout_time - now : 1;
1659 /* When non-wakeable, don't wait more than 100 ms, in any case. */
1660 #define NON_WAKEABLE_POLL_TIMEOUT apr_time_from_msec(100)
1661 if (!listener_is_wakeable
1662 && (timeout_interval < 0
1663 || timeout_interval > NON_WAKEABLE_POLL_TIMEOUT)) {
1664 timeout_interval = NON_WAKEABLE_POLL_TIMEOUT;
1667 rc = apr_pollset_poll(event_pollset, timeout_interval, &num, &out_pfd);
1668 if (rc != APR_SUCCESS) {
1669 if (APR_STATUS_IS_EINTR(rc)) {
1670 /* Woken up, if we are exiting we must fall through to kill
1671 * kept-alive connections, otherwise we only need to update
1672 * timeouts (logic is above, so restart the loop).
1674 if (!listener_may_exit) {
1679 else if (!APR_STATUS_IS_TIMEUP(rc)) {
1680 ap_log_error(APLOG_MARK, APLOG_CRIT, rc, ap_server_conf,
1681 "apr_pollset_poll failed. Attempting to "
1682 "shutdown process gracefully");
1683 signal_threads(ST_GRACEFUL);
1688 if (listener_may_exit) {
1689 close_listeners(process_slot, &closed);
1690 if (terminate_mode == ST_UNGRACEFUL
1691 || apr_atomic_read32(&connection_count) == 0)
1696 pt = (listener_poll_type *) out_pfd->client_data;
1697 if (pt->type == PT_CSD) {
1698 /* one of the sockets is readable */
1699 event_conn_state_t *cs = (event_conn_state_t *) pt->baton;
1700 struct timeout_queue *remove_from_q = cs->sc->wc_q;
1703 switch (cs->pub.state) {
1704 case CONN_STATE_CHECK_REQUEST_LINE_READABLE:
1705 cs->pub.state = CONN_STATE_READ_REQUEST_LINE;
1706 remove_from_q = cs->sc->ka_q;
1707 /* don't wait for a worker for a keepalive request */
1710 case CONN_STATE_WRITE_COMPLETION:
1711 get_worker(&have_idle_worker, blocking,
1712 &workers_were_busy);
1713 apr_thread_mutex_lock(timeout_mutex);
1714 TO_QUEUE_REMOVE(remove_from_q, cs);
1715 rc = apr_pollset_remove(event_pollset, &cs->pfd);
1716 apr_thread_mutex_unlock(timeout_mutex);
1719 * Some of the pollset backends, like KQueue or Epoll
1720 * automagically remove the FD if the socket is closed,
1721 * therefore, we can accept _SUCCESS or _NOTFOUND,
1722 * and we still want to keep going
1724 if (rc != APR_SUCCESS && !APR_STATUS_IS_NOTFOUND(rc)) {
1725 ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
1726 APLOGNO(03094) "pollset remove failed");
1727 start_lingering_close_nonblocking(cs);
1731 /* If we didn't get a worker immediately for a keep-alive
1732 * request, we close the connection, so that the client can
1733 * re-connect to a different process.
1735 if (!have_idle_worker) {
1736 start_lingering_close_nonblocking(cs);
1738 else if (push2worker(cs, NULL, NULL) == APR_SUCCESS) {
1739 have_idle_worker = 0;
1743 case CONN_STATE_LINGER_NORMAL:
1744 case CONN_STATE_LINGER_SHORT:
1745 process_lingering_close(cs, out_pfd);
1749 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1750 ap_server_conf, APLOGNO(03096)
1751 "event_loop: unexpected state %d",
1756 else if (pt->type == PT_ACCEPT) {
1757 /* A Listener Socket is ready for an accept() */
1758 if (workers_were_busy) {
1759 if (!listeners_disabled)
1760 disable_listensocks(process_slot);
1761 listeners_disabled = 1;
1762 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1763 "All workers busy, not accepting new conns "
1766 else if ( (int)apr_atomic_read32(&connection_count)
1767 - (int)apr_atomic_read32(&lingering_count)
1769 + ap_queue_info_get_idlers(worker_queue_info) *
1770 worker_factor / WORKER_FACTOR_SCALE)
1772 if (!listeners_disabled)
1773 disable_listensocks(process_slot);
1774 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1775 "Too many open connections (%u), "
1776 "not accepting new conns in this process",
1777 apr_atomic_read32(&connection_count));
1778 ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
1780 ap_queue_info_get_idlers(worker_queue_info));
1781 listeners_disabled = 1;
1783 else if (listeners_disabled) {
1784 listeners_disabled = 0;
1785 enable_listensocks(process_slot);
1787 if (!listeners_disabled) {
1788 lr = (ap_listen_rec *) pt->baton;
1789 ap_pop_pool(&ptrans, worker_queue_info);
1791 if (ptrans == NULL) {
1792 /* create a new transaction pool for each accepted socket */
1793 apr_allocator_t *allocator;
1795 apr_allocator_create(&allocator);
1796 apr_allocator_max_free_set(allocator,
1798 apr_pool_create_ex(&ptrans, pconf, NULL, allocator);
1799 apr_allocator_owner_set(allocator, ptrans);
1800 if (ptrans == NULL) {
1801 ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
1802 ap_server_conf, APLOGNO(03097)
1803 "Failed to create transaction pool");
1804 signal_threads(ST_GRACEFUL);
1808 apr_pool_tag(ptrans, "transaction");
1810 get_worker(&have_idle_worker, 1, &workers_were_busy);
1811 rc = lr->accept_func(&csd, lr, ptrans);
1813 /* later we trash rv and rely on csd to indicate
1816 AP_DEBUG_ASSERT(rc == APR_SUCCESS || !csd);
1818 if (rc == APR_EGENERAL) {
1819 /* E[NM]FILE, ENOMEM, etc */
1820 resource_shortage = 1;
1821 signal_threads(ST_GRACEFUL);
1826 if (push2worker(NULL, csd, ptrans) == APR_SUCCESS) {
1827 have_idle_worker = 0;
1831 ap_push_pool(worker_queue_info, ptrans);
1834 } /* if:else on pt->type */
1837 } /* while for processing poll */
1839 /* XXX possible optimization: stash the current time for use as
1840 * r->request_time for new requests
1842 /* We process the timeout queues here only when their overall next
1843 * expiry (read once above) is over. This happens accurately since
1844 * adding to the queues (in workers) can only decrease this expiry,
1845 * while latest ones are only taken into account here (in listener)
1846 * during queues' processing, with the lock held. This works both
1847 * with and without wake-ability.
1849 if (timeout_time && timeout_time < (now = apr_time_now())) {
1850 timeout_time = now + TIMEOUT_FUDGE_FACTOR;
1852 /* handle timed out sockets */
1853 apr_thread_mutex_lock(timeout_mutex);
1855 /* Processing all the queues below will recompute this. */
1856 queues_next_expiry = 0;
1858 /* Step 1: keepalive timeouts */
1859 if (workers_were_busy || dying) {
1860 process_keepalive_queue(0); /* kill'em all \m/ */
1863 process_keepalive_queue(timeout_time);
1865 /* Step 2: write completion timeouts */
1866 process_timeout_queue(write_completion_q, timeout_time,
1867 start_lingering_close_nonblocking);
1868 /* Step 3: (normal) lingering close completion timeouts */
1869 process_timeout_queue(linger_q, timeout_time,
1870 stop_lingering_close);
1871 /* Step 4: (short) lingering close completion timeouts */
1872 process_timeout_queue(short_linger_q, timeout_time,
1873 stop_lingering_close);
1875 apr_thread_mutex_unlock(timeout_mutex);
1877 ps->keep_alive = apr_atomic_read32(keepalive_q->total);
1878 ps->write_completion = apr_atomic_read32(write_completion_q->total);
1879 ps->connections = apr_atomic_read32(&connection_count);
1880 ps->suspended = apr_atomic_read32(&suspended_count);
1881 ps->lingering_close = apr_atomic_read32(&lingering_count);
1883 else if ((workers_were_busy || dying)
1884 && apr_atomic_read32(keepalive_q->total)) {
1885 apr_thread_mutex_lock(timeout_mutex);
1886 process_keepalive_queue(0); /* kill'em all \m/ */
1887 apr_thread_mutex_unlock(timeout_mutex);
1891 /* If there are some lingering closes to defer (to a worker), schedule
1892 * them now. We might wakeup a worker spuriously if another one empties
1893 * defer_linger_chain in the meantime, but there also may be no active
1894 * or all busy workers for an undefined time. In any case a deferred
1895 * lingering close can't starve if we do that here since the chain is
1896 * filled only above in the listener and it's emptied only in the
1897 * worker(s); thus a NULL here means it will stay so while the listener
1898 * waits (possibly indefinitely) in poll().
1900 if (defer_linger_chain) {
1901 get_worker(&have_idle_worker, 0, &workers_were_busy);
1902 if (have_idle_worker
1903 && defer_linger_chain /* re-test */
1904 && push2worker(NULL, NULL, NULL) == APR_SUCCESS) {
1905 have_idle_worker = 0;
1909 if (listeners_disabled && !workers_were_busy
1910 && (int)apr_atomic_read32(&connection_count)
1911 - (int)apr_atomic_read32(&lingering_count)
1912 < ((int)ap_queue_info_get_idlers(worker_queue_info) - 1)
1913 * worker_factor / WORKER_FACTOR_SCALE + threads_per_child)
1915 listeners_disabled = 0;
1916 enable_listensocks(process_slot);
1919 * XXX: do we need to set some timeout that re-enables the listensocks
1920 * XXX: in case no other event occurs?
1922 } /* listener main loop */
1924 close_listeners(process_slot, &closed);
1925 ap_queue_term(worker_queue);
1927 apr_thread_exit(thd, APR_SUCCESS);
1932 * During graceful shutdown, if there are more running worker threads than
1933 * open connections, exit one worker thread.
1935 * return 1 if thread should exit, 0 if it should continue running.
1937 static int worker_thread_should_exit_early(void)
1940 apr_uint32_t conns = apr_atomic_read32(&connection_count);
1941 apr_uint32_t dead = apr_atomic_read32(&threads_shutdown);
1942 apr_uint32_t newdead;
1944 AP_DEBUG_ASSERT(dead <= threads_per_child);
1945 if (conns >= threads_per_child - dead)
1949 if (apr_atomic_cas32(&threads_shutdown, newdead, dead) == dead) {
1951 * No other thread has exited in the mean time, safe to exit
1959 /* XXX For ungraceful termination/restart, we definitely don't want to
1960 * wait for active connections to finish but we may want to wait
1961 * for idle workers to get out of the queue code and release mutexes,
1962 * since those mutexes are cleaned up pretty soon and some systems
1963 * may not react favorably (i.e., segfault) if operations are attempted
1964 * on cleaned-up mutexes.
1966 static void *APR_THREAD_FUNC worker_thread(apr_thread_t * thd, void *dummy)
1968 proc_info *ti = dummy;
1969 int process_slot = ti->pslot;
1970 int thread_slot = ti->tslot;
1971 apr_socket_t *csd = NULL;
1972 event_conn_state_t *cs;
1973 apr_pool_t *ptrans; /* Pool for per-transaction stuff */
1976 timer_event_t *te = NULL;
1980 ap_scoreboard_image->servers[process_slot][thread_slot].pid = ap_my_pid;
1981 ap_scoreboard_image->servers[process_slot][thread_slot].tid = apr_os_thread_current();
1982 ap_scoreboard_image->servers[process_slot][thread_slot].generation = retained->mpm->my_generation;
1983 ap_update_child_status_from_indexes(process_slot, thread_slot,
1984 SERVER_STARTING, NULL);
1986 while (!workers_may_exit) {
1988 rv = ap_queue_info_set_idle(worker_queue_info, NULL);
1989 if (rv != APR_SUCCESS) {
1990 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
1991 "ap_queue_info_set_idle failed. Attempting to "
1992 "shutdown process gracefully.");
1993 signal_threads(ST_GRACEFUL);
1999 ap_update_child_status_from_indexes(process_slot, thread_slot,
2000 dying ? SERVER_GRACEFUL
2001 : SERVER_READY, NULL);
2003 if (workers_may_exit) {
2006 if (dying && worker_thread_should_exit_early()) {
2011 rv = ap_queue_pop_something(worker_queue, &csd, &cs, &ptrans, &te);
2013 if (rv != APR_SUCCESS) {
2014 /* We get APR_EOF during a graceful shutdown once all the
2015 * connections accepted by this server process have been handled.
2017 if (APR_STATUS_IS_EOF(rv)) {
2020 /* We get APR_EINTR whenever ap_queue_pop() has been interrupted
2021 * from an explicit call to ap_queue_interrupt_all(). This allows
2022 * us to unblock threads stuck in ap_queue_pop() when a shutdown
2025 * If workers_may_exit is set and this is ungraceful termination/
2026 * restart, we are bound to get an error on some systems (e.g.,
2027 * AIX, which sanity-checks mutex operations) since the queue
2028 * may have already been cleaned up. Don't log the "error" if
2029 * workers_may_exit is set.
2031 else if (APR_STATUS_IS_EINTR(rv)) {
2034 /* We got some other error. */
2035 else if (!workers_may_exit) {
2036 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
2037 APLOGNO(03099) "ap_queue_pop failed");
2042 te->cbfunc(te->baton);
2045 apr_thread_mutex_lock(g_timer_skiplist_mtx);
2046 APR_RING_INSERT_TAIL(&timer_free_ring, te, timer_event_t, link);
2047 apr_thread_mutex_unlock(g_timer_skiplist_mtx);
2053 worker_sockets[thread_slot] = csd;
2054 process_socket(thd, ptrans, csd, cs, process_slot, thread_slot);
2055 worker_sockets[thread_slot] = NULL;
2059 /* If there are deferred lingering closes, handle them now. */
2060 while (!workers_may_exit) {
2061 cs = defer_linger_chain;
2065 if (apr_atomic_casptr((void *)&defer_linger_chain, cs->chain,
2067 /* Race lost, try again */
2072 worker_sockets[thread_slot] = csd = cs->pfd.desc.s;
2074 rv = apr_socket_timeout_set(csd, SECONDS_TO_LINGER);
2075 AP_DEBUG_ASSERT(rv == APR_SUCCESS);
2077 apr_socket_timeout_set(csd, SECONDS_TO_LINGER);
2079 cs->pub.state = CONN_STATE_LINGER;
2080 process_socket(thd, cs->p, csd, cs, process_slot, thread_slot);
2081 worker_sockets[thread_slot] = NULL;
2085 ap_update_child_status_from_indexes(process_slot, thread_slot,
2087 : SERVER_GRACEFUL, NULL);
2089 apr_thread_exit(thd, APR_SUCCESS);
2093 static int check_signal(int signum)
2105 static void create_listener_thread(thread_starter * ts)
2107 int my_child_num = ts->child_num_arg;
2108 apr_threadattr_t *thread_attr = ts->threadattr;
2112 my_info = (proc_info *) ap_malloc(sizeof(proc_info));
2113 my_info->pslot = my_child_num;
2114 my_info->tslot = -1; /* listener thread doesn't have a thread slot */
2115 rv = apr_thread_create(&ts->listener, thread_attr, listener_thread,
2117 if (rv != APR_SUCCESS) {
2118 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(00474)
2119 "apr_thread_create: unable to create listener thread");
2120 /* let the parent decide how bad this really is */
2121 clean_child_exit(APEXIT_CHILDSICK);
2123 apr_os_thread_get(&listener_os_thread, ts->listener);
2126 /* XXX under some circumstances not understood, children can get stuck
2127 * in start_threads forever trying to take over slots which will
2128 * never be cleaned up; for now there is an APLOG_DEBUG message issued
2129 * every so often when this condition occurs
2131 static void *APR_THREAD_FUNC start_threads(apr_thread_t * thd, void *dummy)
2133 thread_starter *ts = dummy;
2134 apr_thread_t **threads = ts->threads;
2135 apr_threadattr_t *thread_attr = ts->threadattr;
2136 int my_child_num = ts->child_num_arg;
2140 int threads_created = 0;
2141 int listener_started = 0;
2143 int prev_threads_created;
2144 int max_recycled_pools = -1;
2145 int good_methods[] = {APR_POLLSET_KQUEUE, APR_POLLSET_PORT, APR_POLLSET_EPOLL};
2146 /* XXX don't we need more to handle K-A or lingering close? */
2147 const apr_uint32_t pollset_size = threads_per_child * 2;
2149 /* We must create the fd queues before we start up the listener
2150 * and worker threads. */
2151 worker_queue = apr_pcalloc(pchild, sizeof(*worker_queue));
2152 rv = ap_queue_init(worker_queue, threads_per_child, pchild);
2153 if (rv != APR_SUCCESS) {
2154 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(03100)
2155 "ap_queue_init() failed");
2156 clean_child_exit(APEXIT_CHILDFATAL);
2159 if (ap_max_mem_free != APR_ALLOCATOR_MAX_FREE_UNLIMITED) {
2160 /* If we want to conserve memory, let's not keep an unlimited number of
2161 * pools & allocators.
2162 * XXX: This should probably be a separate config directive
2164 max_recycled_pools = threads_per_child * 3 / 4 ;
2166 rv = ap_queue_info_create(&worker_queue_info, pchild,
2167 threads_per_child, max_recycled_pools);
2168 if (rv != APR_SUCCESS) {
2169 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(03101)
2170 "ap_queue_info_create() failed");
2171 clean_child_exit(APEXIT_CHILDFATAL);
2174 /* Create the timeout mutex and main pollset before the listener
2177 rv = apr_thread_mutex_create(&timeout_mutex, APR_THREAD_MUTEX_DEFAULT,
2179 if (rv != APR_SUCCESS) {
2180 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(03102)
2181 "creation of the timeout mutex failed.");
2182 clean_child_exit(APEXIT_CHILDFATAL);
2185 /* Create the main pollset */
2186 for (i = 0; i < sizeof(good_methods) / sizeof(good_methods[0]); i++) {
2187 apr_uint32_t flags = APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY |
2188 APR_POLLSET_NODEFAULT | APR_POLLSET_WAKEABLE;
2189 rv = apr_pollset_create_ex(&event_pollset, pollset_size, pchild, flags,
2191 if (rv == APR_SUCCESS) {
2192 listener_is_wakeable = 1;
2195 flags &= ~APR_POLLSET_WAKEABLE;
2196 rv = apr_pollset_create_ex(&event_pollset, pollset_size, pchild, flags,
2198 if (rv == APR_SUCCESS) {
2202 if (rv != APR_SUCCESS) {
2203 rv = apr_pollset_create(&event_pollset, pollset_size, pchild,
2204 APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY);
2206 if (rv != APR_SUCCESS) {
2207 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(03103)
2208 "apr_pollset_create with Thread Safety failed.");
2209 clean_child_exit(APEXIT_CHILDFATAL);
2212 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02471)
2213 "start_threads: Using %s (%swakeable)",
2214 apr_pollset_method_name(event_pollset),
2215 listener_is_wakeable ? "" : "not ");
2216 worker_sockets = apr_pcalloc(pchild, threads_per_child
2217 * sizeof(apr_socket_t *));
2219 loops = prev_threads_created = 0;
2221 /* threads_per_child does not include the listener thread */
2222 for (i = 0; i < threads_per_child; i++) {
2224 ap_scoreboard_image->servers[my_child_num][i].status;
2226 if (status != SERVER_DEAD) {
2230 my_info = (proc_info *) ap_malloc(sizeof(proc_info));
2231 my_info->pslot = my_child_num;
2234 /* We are creating threads right now */
2235 ap_update_child_status_from_indexes(my_child_num, i,
2236 SERVER_STARTING, NULL);
2237 /* We let each thread update its own scoreboard entry. This is
2238 * done because it lets us deal with tid better.
2240 rv = apr_thread_create(&threads[i], thread_attr,
2241 worker_thread, my_info, pchild);
2242 if (rv != APR_SUCCESS) {
2243 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
2245 "apr_thread_create: unable to create worker thread");
2246 /* let the parent decide how bad this really is */
2247 clean_child_exit(APEXIT_CHILDSICK);
2252 /* Start the listener only when there are workers available */
2253 if (!listener_started && threads_created) {
2254 create_listener_thread(ts);
2255 listener_started = 1;
2259 if (start_thread_may_exit || threads_created == threads_per_child) {
2262 /* wait for previous generation to clean up an entry */
2263 apr_sleep(apr_time_from_sec(1));
2265 if (loops % 120 == 0) { /* every couple of minutes */
2266 if (prev_threads_created == threads_created) {
2267 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
2268 "child %" APR_PID_T_FMT " isn't taking over "
2269 "slots very quickly (%d of %d)",
2270 ap_my_pid, threads_created,
2273 prev_threads_created = threads_created;
2277 /* What state should this child_main process be listed as in the
2279 * ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING,
2280 * (request_rec *) NULL);
2282 * This state should be listed separately in the scoreboard, in some kind
2283 * of process_status, not mixed in with the worker threads' status.
2284 * "life_status" is almost right, but it's in the worker's structure, and
2285 * the name could be clearer. gla
2287 apr_thread_exit(thd, APR_SUCCESS);
2291 static void join_workers(apr_thread_t * listener, apr_thread_t ** threads)
2294 apr_status_t rv, thread_rv;
2299 /* deal with a rare timing window which affects waking up the
2300 * listener thread... if the signal sent to the listener thread
2301 * is delivered between the time it verifies that the
2302 * listener_may_exit flag is clear and the time it enters a
2303 * blocking syscall, the signal didn't do any good... work around
2304 * that by sleeping briefly and sending it again
2308 while (iter < 10 && !dying) {
2309 /* listener has not stopped accepting yet */
2310 apr_sleep(apr_time_make(0, 500000));
2315 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00475)
2316 "the listener thread didn't stop accepting");
2319 rv = apr_thread_join(&thread_rv, listener);
2320 if (rv != APR_SUCCESS) {
2321 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, APLOGNO(00476)
2322 "apr_thread_join: unable to join listener thread");
2327 for (i = 0; i < threads_per_child; i++) {
2328 if (threads[i]) { /* if we ever created this thread */
2329 rv = apr_thread_join(&thread_rv, threads[i]);
2330 if (rv != APR_SUCCESS) {
2331 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, APLOGNO(00477)
2332 "apr_thread_join: unable to join worker "
2339 static void join_start_thread(apr_thread_t * start_thread_id)
2341 apr_status_t rv, thread_rv;
2343 start_thread_may_exit = 1; /* tell it to give up in case it is still
2344 * trying to take over slots from a
2345 * previous generation
2347 rv = apr_thread_join(&thread_rv, start_thread_id);
2348 if (rv != APR_SUCCESS) {
2349 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, APLOGNO(00478)
2350 "apr_thread_join: unable to join the start " "thread");
2354 static void child_main(int child_num_arg, int child_bucket)
2356 apr_thread_t **threads;
2359 apr_threadattr_t *thread_attr;
2360 apr_thread_t *start_thread_id;
2363 /* for benefit of any hooks that run as this child initializes */
2364 retained->mpm->mpm_state = AP_MPMQ_STARTING;
2366 ap_my_pid = getpid();
2367 ap_fatal_signal_child_setup(ap_server_conf);
2368 apr_pool_create(&pchild, pconf);
2370 /* close unused listeners and pods */
2371 for (i = 0; i < retained->mpm->num_buckets; i++) {
2372 if (i != child_bucket) {
2373 ap_close_listeners_ex(all_buckets[i].listeners);
2374 ap_mpm_podx_close(all_buckets[i].pod);
2378 /*stuff to do before we switch id's, so we have permissions. */
2379 ap_reopen_scoreboard(pchild, NULL, 0);
2381 if (ap_run_drop_privileges(pchild, ap_server_conf)) {
2382 clean_child_exit(APEXIT_CHILDFATAL);
2385 apr_thread_mutex_create(&g_timer_skiplist_mtx, APR_THREAD_MUTEX_DEFAULT, pchild);
2386 APR_RING_INIT(&timer_free_ring, timer_event_t, link);
2387 apr_skiplist_init(&timer_skiplist, pchild);
2388 apr_skiplist_set_compare(timer_skiplist, timer_comp, timer_comp);
2389 ap_run_child_init(pchild, ap_server_conf);
2391 /* done with init critical section */
2393 /* Just use the standard apr_setup_signal_thread to block all signals
2394 * from being received. The child processes no longer use signals for
2395 * any communication with the parent process.
2397 rv = apr_setup_signal_thread();
2398 if (rv != APR_SUCCESS) {
2399 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, APLOGNO(00479)
2400 "Couldn't initialize signal thread");
2401 clean_child_exit(APEXIT_CHILDFATAL);
2404 if (ap_max_requests_per_child) {
2405 conns_this_child = ap_max_requests_per_child;
2408 /* coding a value of zero means infinity */
2409 conns_this_child = APR_INT32_MAX;
2412 /* Setup worker threads */
2414 /* clear the storage; we may not create all our threads immediately,
2415 * and we want a 0 entry to indicate a thread which was not created
2417 threads = ap_calloc(threads_per_child, sizeof(apr_thread_t *));
2418 ts = apr_palloc(pchild, sizeof(*ts));
2420 apr_threadattr_create(&thread_attr, pchild);
2421 /* 0 means PTHREAD_CREATE_JOINABLE */
2422 apr_threadattr_detach_set(thread_attr, 0);
2424 if (ap_thread_stacksize != 0) {
2425 rv = apr_threadattr_stacksize_set(thread_attr, ap_thread_stacksize);
2426 if (rv != APR_SUCCESS && rv != APR_ENOTIMPL) {
2427 ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, APLOGNO(02436)
2428 "WARNING: ThreadStackSize of %" APR_SIZE_T_FMT " is "
2429 "inappropriate, using default",
2430 ap_thread_stacksize);
2434 ts->threads = threads;
2435 ts->listener = NULL;
2436 ts->child_num_arg = child_num_arg;
2437 ts->threadattr = thread_attr;
2439 rv = apr_thread_create(&start_thread_id, thread_attr, start_threads,
2441 if (rv != APR_SUCCESS) {
2442 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(00480)
2443 "apr_thread_create: unable to create worker thread");
2444 /* let the parent decide how bad this really is */
2445 clean_child_exit(APEXIT_CHILDSICK);
2448 retained->mpm->mpm_state = AP_MPMQ_RUNNING;
2450 /* If we are only running in one_process mode, we will want to
2451 * still handle signals. */
2453 /* Block until we get a terminating signal. */
2454 apr_signal_thread(check_signal);
2455 /* make sure the start thread has finished; signal_threads()
2456 * and join_workers() depend on that
2458 /* XXX join_start_thread() won't be awakened if one of our
2459 * threads encounters a critical error and attempts to
2460 * shutdown this child
2462 join_start_thread(start_thread_id);
2464 /* helps us terminate a little more quickly than the dispatch of the
2465 * signal thread; beats the Pipe of Death and the browsers
2467 signal_threads(ST_UNGRACEFUL);
2469 /* A terminating signal was received. Now join each of the
2470 * workers to clean them up.
2471 * If the worker already exited, then the join frees
2472 * their resources and returns.
2473 * If the worker hasn't exited, then this blocks until
2474 * they have (then cleans up).
2476 join_workers(ts->listener, threads);
2478 else { /* !one_process */
2479 /* remove SIGTERM from the set of blocked signals... if one of
2480 * the other threads in the process needs to take us down
2481 * (e.g., for MaxConnectionsPerChild) it will send us SIGTERM
2483 unblock_signal(SIGTERM);
2484 apr_signal(SIGTERM, dummy_signal_handler);
2485 /* Watch for any messages from the parent over the POD */
2487 rv = ap_mpm_podx_check(my_bucket->pod);
2488 if (rv == AP_MPM_PODX_NORESTART) {
2489 /* see if termination was triggered while we slept */
2490 switch (terminate_mode) {
2492 rv = AP_MPM_PODX_GRACEFUL;
2495 rv = AP_MPM_PODX_RESTART;
2499 if (rv == AP_MPM_PODX_GRACEFUL || rv == AP_MPM_PODX_RESTART) {
2500 /* make sure the start thread has finished;
2501 * signal_threads() and join_workers depend on that
2503 join_start_thread(start_thread_id);
2504 signal_threads(rv ==
2505 AP_MPM_PODX_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL);
2510 /* A terminating signal was received. Now join each of the
2511 * workers to clean them up.
2512 * If the worker already exited, then the join frees
2513 * their resources and returns.
2514 * If the worker hasn't exited, then this blocks until
2515 * they have (then cleans up).
2517 join_workers(ts->listener, threads);
2522 clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0);
2525 static int make_child(server_rec * s, int slot, int bucket)
2529 if (slot + 1 > retained->max_daemons_limit) {
2530 retained->max_daemons_limit = slot + 1;
2533 if (ap_scoreboard_image->parent[slot].pid != 0) {
2534 /* XXX replace with assert or remove ? */
2535 ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(03455)
2536 "BUG: Scoreboard slot %d should be empty but is "
2537 "in use by pid %" APR_PID_T_FMT,
2538 slot, ap_scoreboard_image->parent[slot].pid);
2543 my_bucket = &all_buckets[0];
2545 event_note_child_started(slot, getpid());
2546 child_main(slot, 0);
2552 if ((pid = fork()) == -1) {
2553 ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, APLOGNO(00481)
2554 "fork: Unable to fork new process");
2556 /* fork didn't succeed. There's no need to touch the scoreboard;
2557 * if we were trying to replace a failed child process, then
2558 * server_main_loop() marked its workers SERVER_DEAD, and if
2559 * we were trying to replace a child process that exited normally,
2560 * its worker_thread()s left SERVER_DEAD or SERVER_GRACEFUL behind.
2563 /* In case system resources are maxxed out, we don't want
2564 Apache running away with the CPU trying to fork over and
2565 over and over again. */
2566 apr_sleep(apr_time_from_sec(10));
2572 my_bucket = &all_buckets[bucket];
2574 #ifdef HAVE_BINDPROCESSOR
2575 /* By default, AIX binds to a single processor. This bit unbinds
2576 * children which will then bind to another CPU.
2578 int status = bindprocessor(BINDPROCESS, (int) getpid(),
2579 PROCESSOR_CLASS_ANY);
2581 ap_log_error(APLOG_MARK, APLOG_DEBUG, errno,
2582 ap_server_conf, APLOGNO(00482)
2583 "processor unbind failed");
2585 RAISE_SIGSTOP(MAKE_CHILD);
2587 apr_signal(SIGTERM, just_die);
2588 child_main(slot, bucket);
2594 ap_scoreboard_image->parent[slot].quiescing = 0;
2595 ap_scoreboard_image->parent[slot].not_accepting = 0;
2596 ap_scoreboard_image->parent[slot].bucket = bucket;
2597 event_note_child_started(slot, pid);
2599 retained->total_daemons++;
2603 /* start up a bunch of children */
2604 static void startup_children(int number_to_start)
2608 for (i = 0; number_to_start && i < server_limit; ++i) {
2609 if (ap_scoreboard_image->parent[i].pid != 0) {
2612 if (make_child(ap_server_conf, i, i % retained->mpm->num_buckets) < 0) {
2619 static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
2622 int idle_thread_count = 0;
2625 int free_length = 0;
2626 int free_slots[MAX_SPAWN_RATE];
2627 int last_non_dead = -1;
2628 int active_thread_count = 0;
2630 for (i = 0; i < server_limit; ++i) {
2631 /* Initialization to satisfy the compiler. It doesn't know
2632 * that threads_per_child is always > 0 */
2633 int status = SERVER_DEAD;
2634 int child_threads_active = 0;
2636 if (i >= retained->max_daemons_limit &&
2637 free_length == retained->idle_spawn_rate[child_bucket]) {
2638 /* short cut if all active processes have been examined and
2639 * enough empty scoreboard slots have been found
2644 ps = &ap_scoreboard_image->parent[i];
2646 for (j = 0; j < threads_per_child; j++) {
2647 ws = &ap_scoreboard_image->servers[i][j];
2648 status = ws->status;
2650 /* We consider a starting server as idle because we started it
2651 * at least a cycle ago, and if it still hasn't finished starting
2652 * then we're just going to swamp things worse by forking more.
2653 * So we hopefully won't need to fork more if we count it.
2654 * This depends on the ordering of SERVER_READY and SERVER_STARTING.
2656 if (status <= SERVER_READY && !ps->quiescing && !ps->not_accepting
2657 && ps->generation == retained->mpm->my_generation
2658 && ps->bucket == child_bucket)
2660 ++idle_thread_count;
2662 if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
2663 ++child_threads_active;
2668 active_thread_count += child_threads_active;
2669 if (!ps->pid && free_length < retained->idle_spawn_rate[child_bucket])
2670 free_slots[free_length++] = i;
2671 else if (child_threads_active == threads_per_child)
2672 had_healthy_child = 1;
2675 if (retained->sick_child_detected) {
2676 if (had_healthy_child) {
2677 /* Assume this is a transient error, even though it may not be. Leave
2678 * the server up in case it is able to serve some requests or the
2679 * problem will be resolved.
2681 retained->sick_child_detected = 0;
2684 /* looks like a basket case, as no child ever fully initialized; give up.
2686 retained->mpm->shutdown_pending = 1;
2688 ap_log_error(APLOG_MARK, APLOG_ALERT, 0,
2689 ap_server_conf, APLOGNO(02324)
2690 "A resource shortage or other unrecoverable failure "
2691 "was encountered before any child process initialized "
2692 "successfully... httpd is exiting!");
2693 /* the child already logged the failure details */
2698 retained->max_daemons_limit = last_non_dead + 1;
2700 if (idle_thread_count > max_spare_threads / num_buckets)
2703 * Child processes that we ask to shut down won't die immediately
2704 * but may stay around for a long time when they finish their
2705 * requests. If the server load changes many times, many such
2706 * gracefully finishing processes may accumulate, filling up the
2707 * scoreboard. To avoid running out of scoreboard entries, we
2708 * don't shut down more processes when the total number of processes
2711 * XXX It would be nice if we could
2712 * XXX - kill processes without keepalive connections first
2713 * XXX - tell children to stop accepting new connections, and
2714 * XXX depending on server load, later be able to resurrect them
2717 if (retained->total_daemons <= active_daemons_limit &&
2718 retained->total_daemons < server_limit) {
2719 /* Kill off one child */
2720 ap_mpm_podx_signal(all_buckets[child_bucket].pod,
2721 AP_MPM_PODX_GRACEFUL);
2722 retained->idle_spawn_rate[child_bucket] = 1;
2725 ap_log_error(APLOG_MARK, APLOG_TRACE5, 0, ap_server_conf,
2726 "Not shutting down child: total daemons %d / "
2727 "active limit %d / ServerLimit %d",
2728 retained->total_daemons, active_daemons_limit,
2732 else if (idle_thread_count < min_spare_threads / num_buckets) {
2733 if (active_thread_count >= max_workers) {
2734 if (!retained->maxclients_reported) {
2735 /* only report this condition once */
2736 ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(00484)
2737 "server reached MaxRequestWorkers setting, "
2738 "consider raising the MaxRequestWorkers "
2740 retained->maxclients_reported = 1;
2742 retained->idle_spawn_rate[child_bucket] = 1;
2744 else if (free_length == 0) { /* scoreboard is full, can't fork */
2745 ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(03490)
2746 "scoreboard is full, not at MaxRequestWorkers."
2747 "Increase ServerLimit.");
2748 retained->idle_spawn_rate[child_bucket] = 1;
2751 if (free_length > retained->idle_spawn_rate[child_bucket]) {
2752 free_length = retained->idle_spawn_rate[child_bucket];
2754 if (retained->idle_spawn_rate[child_bucket] >= 8) {
2755 ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00486)
2756 "server seems busy, (you may need "
2757 "to increase StartServers, ThreadsPerChild "
2758 "or Min/MaxSpareThreads), "
2759 "spawning %d children, there are around %d idle "
2760 "threads, %d active children, and %d children "
2761 "that are shutting down", free_length,
2762 idle_thread_count, active_daemons,
2763 retained->total_daemons);
2765 for (i = 0; i < free_length; ++i) {
2766 ap_log_error(APLOG_MARK, APLOG_TRACE5, 0, ap_server_conf,
2767 "Spawning new child: slot %d active / "
2768 "total daemons: %d/%d",
2769 free_slots[i], active_daemons,
2770 retained->total_daemons);
2771 make_child(ap_server_conf, free_slots[i], child_bucket);
2773 /* the next time around we want to spawn twice as many if this
2774 * wasn't good enough, but not if we've just done a graceful
2776 if (retained->hold_off_on_exponential_spawning) {
2777 --retained->hold_off_on_exponential_spawning;
2779 else if (retained->idle_spawn_rate[child_bucket]
2780 < MAX_SPAWN_RATE / num_buckets) {
2781 retained->idle_spawn_rate[child_bucket] *= 2;
2786 retained->idle_spawn_rate[child_bucket] = 1;
2790 static void server_main_loop(int remaining_children_to_start, int num_buckets)
2793 apr_exit_why_e exitwhy;
2794 int status, processed_status;
2798 while (!retained->mpm->restart_pending && !retained->mpm->shutdown_pending) {
2799 ap_wait_or_timeout(&exitwhy, &status, &pid, pconf, ap_server_conf);
2801 if (pid.pid != -1) {
2802 processed_status = ap_process_child_status(&pid, exitwhy, status);
2803 child_slot = ap_find_child_by_pid(&pid);
2804 if (processed_status == APEXIT_CHILDFATAL) {
2805 /* fix race condition found in PR 39311
2806 * A child created at the same time as a graceful happens
2807 * can find the lock missing and create a fatal error.
2808 * It is not fatal for the last generation to be in this state.
2811 || ap_get_scoreboard_process(child_slot)->generation
2812 == retained->mpm->my_generation) {
2813 retained->mpm->shutdown_pending = 1;
2816 * total_daemons counting will be off now, but as we
2817 * are shutting down, that is not an issue anymore.
2822 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf, APLOGNO(00487)
2823 "Ignoring fatal error in child of previous "
2824 "generation (pid %ld).",
2826 retained->sick_child_detected = 1;
2829 else if (processed_status == APEXIT_CHILDSICK) {
2830 /* tell perform_idle_server_maintenance to check into this
2831 * on the next timer pop
2833 retained->sick_child_detected = 1;
2835 /* non-fatal death... note that it's gone in the scoreboard. */
2836 if (child_slot >= 0) {
2839 for (i = 0; i < threads_per_child; i++)
2840 ap_update_child_status_from_indexes(child_slot, i,
2843 event_note_child_killed(child_slot, 0, 0);
2844 ps = &ap_scoreboard_image->parent[child_slot];
2848 /* NOTE: We don't dec in the (child_slot < 0) case! */
2849 retained->total_daemons--;
2850 if (processed_status == APEXIT_CHILDSICK) {
2851 /* resource shortage, minimize the fork rate */
2852 retained->idle_spawn_rate[ps->bucket] = 1;
2854 else if (remaining_children_to_start) {
2855 /* we're still doing a 1-for-1 replacement of dead
2856 * children with new children
2858 make_child(ap_server_conf, child_slot, ps->bucket);
2859 --remaining_children_to_start;
2862 #if APR_HAS_OTHER_CHILD
2863 else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH,
2868 else if (retained->mpm->was_graceful) {
2869 /* Great, we've probably just lost a slot in the
2870 * scoreboard. Somehow we don't know about this child.
2872 ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
2873 ap_server_conf, APLOGNO(00488)
2874 "long lost child came home! (pid %ld)",
2877 /* Don't perform idle maintenance when a child dies,
2878 * only do it when there's a timeout. Remember only a
2879 * finite number of children can die, and it's pretty
2880 * pathological for a lot to die suddenly.
2884 else if (remaining_children_to_start) {
2885 /* we hit a 1 second timeout in which none of the previous
2886 * generation of children needed to be reaped... so assume
2887 * they're all done, and pick up the slack if any is left.
2889 startup_children(remaining_children_to_start);
2890 remaining_children_to_start = 0;
2891 /* In any event we really shouldn't do the code below because
2892 * few of the servers we just started are in the IDLE state
2893 * yet, so we'd mistakenly create an extra server.
2898 for (i = 0; i < num_buckets; i++) {
2899 perform_idle_server_maintenance(i, num_buckets);
2904 static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
2906 int num_buckets = retained->mpm->num_buckets;
2907 int remaining_children_to_start;
2910 ap_log_pid(pconf, ap_pid_fname);
2912 if (!retained->mpm->was_graceful) {
2913 if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
2914 retained->mpm->mpm_state = AP_MPMQ_STOPPING;
2917 /* fix the generation number in the global score; we just got a new,
2918 * cleared scoreboard
2920 ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
2923 ap_unixd_mpm_set_signals(pconf, one_process);
2925 /* Don't thrash since num_buckets depends on the
2926 * system and the number of online CPU cores...
2928 if (active_daemons_limit < num_buckets)
2929 active_daemons_limit = num_buckets;
2930 if (ap_daemons_to_start < num_buckets)
2931 ap_daemons_to_start = num_buckets;
2932 /* We want to create as much children at a time as the number of buckets,
2933 * so to optimally accept connections (evenly distributed across buckets).
2934 * Thus min_spare_threads should at least maintain num_buckets children,
2935 * and max_spare_threads allow num_buckets more children w/o triggering
2936 * immediately (e.g. num_buckets idle threads margin, one per bucket).
2938 if (min_spare_threads < threads_per_child * (num_buckets - 1) + num_buckets)
2939 min_spare_threads = threads_per_child * (num_buckets - 1) + num_buckets;
2940 if (max_spare_threads < min_spare_threads + (threads_per_child + 1) * num_buckets)
2941 max_spare_threads = min_spare_threads + (threads_per_child + 1) * num_buckets;
2943 /* If we're doing a graceful_restart then we're going to see a lot
2944 * of children exiting immediately when we get into the main loop
2945 * below (because we just sent them AP_SIG_GRACEFUL). This happens pretty
2946 * rapidly... and for each one that exits we may start a new one, until
2947 * there are at least min_spare_threads idle threads, counting across
2948 * all children. But we may be permitted to start more children than
2949 * that, so we'll just keep track of how many we're
2950 * supposed to start up without the 1 second penalty between each fork.
2952 remaining_children_to_start = ap_daemons_to_start;
2953 if (remaining_children_to_start > active_daemons_limit) {
2954 remaining_children_to_start = active_daemons_limit;
2956 if (!retained->mpm->was_graceful) {
2957 startup_children(remaining_children_to_start);
2958 remaining_children_to_start = 0;
2961 /* give the system some time to recover before kicking into
2962 * exponential mode */
2963 retained->hold_off_on_exponential_spawning = 10;
2966 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00489)
2967 "%s configured -- resuming normal operations",
2968 ap_get_server_description());
2969 ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00490)
2970 "Server built: %s", ap_get_server_built());
2971 ap_log_command_line(plog, s);
2972 ap_log_mpm_common(s);
2974 retained->mpm->mpm_state = AP_MPMQ_RUNNING;
2976 server_main_loop(remaining_children_to_start, num_buckets);
2977 retained->mpm->mpm_state = AP_MPMQ_STOPPING;
2979 if (retained->mpm->shutdown_pending && retained->mpm->is_ungraceful) {
2980 /* Time to shut down:
2981 * Kill child processes, tell them to call child_exit, etc...
2983 for (i = 0; i < num_buckets; i++) {
2984 ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
2985 AP_MPM_PODX_RESTART);
2987 ap_reclaim_child_processes(1, /* Start with SIGTERM */
2988 event_note_child_killed);
2991 /* cleanup pid file on normal shutdown */
2992 ap_remove_pid(pconf, ap_pid_fname);
2993 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,
2994 ap_server_conf, APLOGNO(00491) "caught SIGTERM, shutting down");
3000 if (retained->mpm->shutdown_pending) {
3001 /* Time to gracefully shut down:
3002 * Kill child processes, tell them to call child_exit, etc...
3004 int active_children;
3006 apr_time_t cutoff = 0;
3008 /* Close our listeners, and then ask our children to do same */
3009 ap_close_listeners();
3010 for (i = 0; i < num_buckets; i++) {
3011 ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
3012 AP_MPM_PODX_GRACEFUL);
3014 ap_relieve_child_processes(event_note_child_killed);
3017 /* cleanup pid file on normal shutdown */
3018 ap_remove_pid(pconf, ap_pid_fname);
3019 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00492)
3020 "caught " AP_SIG_GRACEFUL_STOP_STRING
3021 ", shutting down gracefully");
3024 if (ap_graceful_shutdown_timeout) {
3025 cutoff = apr_time_now() +
3026 apr_time_from_sec(ap_graceful_shutdown_timeout);
3029 /* Don't really exit until each child has finished */
3030 retained->mpm->shutdown_pending = 0;
3032 /* Pause for a second */
3033 apr_sleep(apr_time_from_sec(1));
3035 /* Relieve any children which have now exited */
3036 ap_relieve_child_processes(event_note_child_killed);
3038 active_children = 0;
3039 for (index = 0; index < retained->max_daemons_limit; ++index) {
3040 if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == APR_SUCCESS) {
3041 active_children = 1;
3042 /* Having just one child is enough to stay around */
3046 } while (!retained->mpm->shutdown_pending && active_children &&
3047 (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
3049 /* We might be here because we received SIGTERM, either
3050 * way, try and make sure that all of our processes are
3053 for (i = 0; i < num_buckets; i++) {
3054 ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
3055 AP_MPM_PODX_RESTART);
3057 ap_reclaim_child_processes(1, event_note_child_killed);
3062 /* we've been told to restart */
3064 /* not worth thinking about */
3068 /* advance to the next generation */
3069 /* XXX: we really need to make sure this new generation number isn't in
3070 * use by any of the children.
3072 ++retained->mpm->my_generation;
3073 ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
3075 if (!retained->mpm->is_ungraceful) {
3076 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00493)
3077 AP_SIG_GRACEFUL_STRING
3078 " received. Doing graceful restart");
3079 /* wake up the children...time to die. But we'll have more soon */
3080 for (i = 0; i < num_buckets; i++) {
3081 ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
3082 AP_MPM_PODX_GRACEFUL);
3085 /* This is mostly for debugging... so that we know what is still
3086 * gracefully dealing with existing request.
3091 /* Kill 'em all. Since the child acts the same on the parents SIGTERM
3092 * and a SIGHUP, we may as well use the same signal, because some user
3093 * pthreads are stealing signals from us left and right.
3095 for (i = 0; i < num_buckets; i++) {
3096 ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
3097 AP_MPM_PODX_RESTART);
3100 ap_reclaim_child_processes(1, /* Start with SIGTERM */
3101 event_note_child_killed);
3102 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00494)
3103 "SIGHUP received. Attempting to restart");
3111 static void setup_slave_conn(conn_rec *c, void *csd)
3113 event_conn_state_t *mcs;
3114 event_conn_state_t *cs;
3116 mcs = ap_get_module_config(c->master->conn_config, &mpm_event_module);
3118 cs = apr_pcalloc(c->pool, sizeof(*cs));
3124 cs->bucket_alloc = c->bucket_alloc;
3127 cs->pub.state = CONN_STATE_READ_REQUEST_LINE;
3128 cs->pub.sense = CONN_SENSE_DEFAULT;
3131 ap_set_module_config(c->conn_config, &mpm_event_module, cs);
3134 static int event_pre_connection(conn_rec *c, void *csd)
3136 if (c->master && (!c->cs || c->cs == c->master->cs)) {
3137 setup_slave_conn(c, csd);
3142 static int event_protocol_switch(conn_rec *c, request_rec *r, server_rec *s,
3143 const char *protocol)
3146 /* connection based switching of protocol, set the correct server
3147 * configuration, so that timeouts, keepalives and such are used
3148 * for the server that the connection was switched on.
3149 * Normally, we set this on post_read_request, but on a protocol
3150 * other than http/1.1, this might never happen.
3152 event_conn_state_t *cs;
3154 cs = ap_get_module_config(c->conn_config, &mpm_event_module);
3155 cs->sc = ap_get_module_config(s->module_config, &mpm_event_module);
3160 /* This really should be a post_config hook, but the error log is already
3161 * redirected by that point, so we need to do this in the open_logs phase.
3163 static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
3164 apr_pool_t * ptemp, server_rec * s)
3167 int level_flags = 0;
3168 int num_buckets = 0;
3169 ap_listen_rec **listen_buckets;
3175 /* the reverse of pre_config, we want this only the first time around */
3176 if (retained->mpm->module_loads == 1) {
3178 level_flags |= APLOG_STARTUP;
3181 if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {
3182 ap_log_error(APLOG_MARK, APLOG_ALERT | level_flags, 0,
3183 (startup ? NULL : s),
3184 "no listening sockets available, shutting down");
3191 else if (retained->mpm->was_graceful) {
3192 /* Preserve the number of buckets on graceful restarts. */
3193 num_buckets = retained->mpm->num_buckets;
3195 if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
3196 &listen_buckets, &num_buckets))) {
3197 ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
3198 (startup ? NULL : s),
3199 "could not duplicate listeners");
3203 all_buckets = apr_pcalloc(pconf, num_buckets * sizeof(*all_buckets));
3204 for (i = 0; i < num_buckets; i++) {
3205 if (!one_process && /* no POD in one_process mode */
3206 (rv = ap_mpm_podx_open(pconf, &all_buckets[i].pod))) {
3207 ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
3208 (startup ? NULL : s),
3209 "could not open pipe-of-death");
3212 all_buckets[i].listeners = listen_buckets[i];
3215 if (retained->mpm->max_buckets < num_buckets) {
3216 int new_max, *new_ptr;
3217 new_max = retained->mpm->max_buckets * 2;
3218 if (new_max < num_buckets) {
3219 new_max = num_buckets;
3221 new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
3222 memcpy(new_ptr, retained->idle_spawn_rate,
3223 retained->mpm->num_buckets * sizeof(int));
3224 retained->idle_spawn_rate = new_ptr;
3225 retained->mpm->max_buckets = new_max;
3227 if (retained->mpm->num_buckets < num_buckets) {
3229 /* If new buckets are added, set their idle spawn rate to
3230 * the highest so far, so that they get filled as quickly
3231 * as the existing ones.
3233 for (i = 0; i < retained->mpm->num_buckets; i++) {
3234 if (rate_max < retained->idle_spawn_rate[i]) {
3235 rate_max = retained->idle_spawn_rate[i];
3238 for (/* up to date i */; i < num_buckets; i++) {
3239 retained->idle_spawn_rate[i] = rate_max;
3242 retained->mpm->num_buckets = num_buckets;
3245 srand((unsigned int)apr_time_now());
3249 static int event_pre_config(apr_pool_t * pconf, apr_pool_t * plog,
3252 int no_detach, debug, foreground;
3254 const char *userdata_key = "mpm_event_module";
3255 int test_atomics = 0;
3257 debug = ap_exists_config_define("DEBUG");
3260 foreground = one_process = 1;
3264 one_process = ap_exists_config_define("ONE_PROCESS");
3265 no_detach = ap_exists_config_define("NO_DETACH");
3266 foreground = ap_exists_config_define("FOREGROUND");
3269 retained = ap_retained_data_get(userdata_key);
3271 retained = ap_retained_data_create(userdata_key, sizeof(*retained));
3272 retained->mpm = ap_unixd_mpm_get_retained_data();
3273 retained->max_daemons_limit = -1;
3274 if (retained->mpm->module_loads) {
3278 retained->mpm->mpm_state = AP_MPMQ_STARTING;
3279 if (retained->mpm->baton != retained) {
3280 retained->mpm->was_graceful = 0;
3281 retained->mpm->baton = retained;
3283 ++retained->mpm->module_loads;
3285 /* test once for correct operation of fdqueue */
3286 if (test_atomics || retained->mpm->module_loads == 2) {
3287 static apr_uint32_t foo1, foo2;
3289 apr_atomic_set32(&foo1, 100);
3290 foo2 = apr_atomic_add32(&foo1, -10);
3291 if (foo2 != 100 || foo1 != 90) {
3292 ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, APLOGNO(02405)
3293 "atomics not working as expected - add32 of negative number");
3294 return HTTP_INTERNAL_SERVER_ERROR;
3298 /* sigh, want this only the second time around */
3299 if (retained->mpm->module_loads == 2) {
3300 rv = apr_pollset_create(&event_pollset, 1, plog,
3301 APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY);
3302 if (rv != APR_SUCCESS) {
3303 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, APLOGNO(00495)
3304 "Couldn't create a Thread Safe Pollset. "
3305 "Is it supported on your platform?"
3306 "Also check system or user limits!");
3307 return HTTP_INTERNAL_SERVER_ERROR;
3309 apr_pollset_destroy(event_pollset);
3311 if (!one_process && !foreground) {
3312 /* before we detach, setup crash handlers to log to errorlog */
3313 ap_fatal_signal_setup(ap_server_conf, pconf);
3314 rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND
3315 : APR_PROC_DETACH_DAEMONIZE);
3316 if (rv != APR_SUCCESS) {
3317 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, APLOGNO(00496)
3318 "apr_proc_detach failed");
3319 return HTTP_INTERNAL_SERVER_ERROR;
3324 parent_pid = ap_my_pid = getpid();
3326 ap_listen_pre_config();
3327 ap_daemons_to_start = DEFAULT_START_DAEMON;
3328 min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
3329 max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
3330 server_limit = DEFAULT_SERVER_LIMIT;
3331 thread_limit = DEFAULT_THREAD_LIMIT;
3332 active_daemons_limit = server_limit;
3333 threads_per_child = DEFAULT_THREADS_PER_CHILD;
3334 max_workers = active_daemons_limit * threads_per_child;
3335 defer_linger_chain = NULL;
3336 had_healthy_child = 0;
3337 ap_extended_status = 0;
3342 static int event_post_config(apr_pool_t *pconf, apr_pool_t *plog,
3343 apr_pool_t *ptemp, server_rec *s)
3346 struct timeout_queue *tail, *q;
3350 /* Not needed in pre_config stage */
3351 if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
3355 wc.tail = ka.tail = NULL;
3356 wc.hash = apr_hash_make(ptemp);
3357 ka.hash = apr_hash_make(ptemp);
3359 linger_q = TO_QUEUE_MAKE(pconf, apr_time_from_sec(MAX_SECS_TO_LINGER),
3361 short_linger_q = TO_QUEUE_MAKE(pconf, apr_time_from_sec(SECONDS_TO_LINGER),
3364 for (; s; s = s->next) {
3365 event_srv_cfg *sc = apr_pcalloc(pconf, sizeof *sc);
3367 ap_set_module_config(s->module_config, &mpm_event_module, sc);
3369 /* The main server uses the global queues */
3370 wc.q = TO_QUEUE_MAKE(pconf, s->timeout, NULL);
3371 apr_hash_set(wc.hash, &s->timeout, sizeof s->timeout, wc.q);
3372 wc.tail = write_completion_q = wc.q;
3374 ka.q = TO_QUEUE_MAKE(pconf, s->keep_alive_timeout, NULL);
3375 apr_hash_set(ka.hash, &s->keep_alive_timeout,
3376 sizeof s->keep_alive_timeout, ka.q);
3377 ka.tail = keepalive_q = ka.q;
3380 /* The vhosts use any existing queue with the same timeout,
3381 * or their own queue(s) if there isn't */
3382 wc.q = apr_hash_get(wc.hash, &s->timeout, sizeof s->timeout);
3384 wc.q = TO_QUEUE_MAKE(pconf, s->timeout, wc.tail);
3385 apr_hash_set(wc.hash, &s->timeout, sizeof s->timeout, wc.q);
3386 wc.tail = wc.tail->next = wc.q;
3389 ka.q = apr_hash_get(ka.hash, &s->keep_alive_timeout,
3390 sizeof s->keep_alive_timeout);
3392 ka.q = TO_QUEUE_MAKE(pconf, s->keep_alive_timeout, ka.tail);
3393 apr_hash_set(ka.hash, &s->keep_alive_timeout,
3394 sizeof s->keep_alive_timeout, ka.q);
3395 ka.tail = ka.tail->next = ka.q;
3405 static int event_check_config(apr_pool_t *p, apr_pool_t *plog,
3406 apr_pool_t *ptemp, server_rec *s)
3410 /* the reverse of pre_config, we want this only the first time around */
3411 if (retained->mpm->module_loads == 1) {
3415 if (server_limit > MAX_SERVER_LIMIT) {
3417 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00497)
3418 "WARNING: ServerLimit of %d exceeds compile-time "
3419 "limit of %d servers, decreasing to %d.",
3420 server_limit, MAX_SERVER_LIMIT, MAX_SERVER_LIMIT);
3422 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00498)
3423 "ServerLimit of %d exceeds compile-time limit "
3424 "of %d, decreasing to match",
3425 server_limit, MAX_SERVER_LIMIT);
3427 server_limit = MAX_SERVER_LIMIT;
3429 else if (server_limit < 1) {
3431 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00499)
3432 "WARNING: ServerLimit of %d not allowed, "
3433 "increasing to 1.", server_limit);
3435 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00500)
3436 "ServerLimit of %d not allowed, increasing to 1",
3442 /* you cannot change ServerLimit across a restart; ignore
3445 if (!retained->first_server_limit) {
3446 retained->first_server_limit = server_limit;
3448 else if (server_limit != retained->first_server_limit) {
3449 /* don't need a startup console version here */
3450 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00501)
3451 "changing ServerLimit to %d from original value of %d "
3452 "not allowed during restart",
3453 server_limit, retained->first_server_limit);
3454 server_limit = retained->first_server_limit;
3457 if (thread_limit > MAX_THREAD_LIMIT) {
3459 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00502)
3460 "WARNING: ThreadLimit of %d exceeds compile-time "
3461 "limit of %d threads, decreasing to %d.",
3462 thread_limit, MAX_THREAD_LIMIT, MAX_THREAD_LIMIT);
3464 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00503)
3465 "ThreadLimit of %d exceeds compile-time limit "
3466 "of %d, decreasing to match",
3467 thread_limit, MAX_THREAD_LIMIT);
3469 thread_limit = MAX_THREAD_LIMIT;
3471 else if (thread_limit < 1) {
3473 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00504)
3474 "WARNING: ThreadLimit of %d not allowed, "
3475 "increasing to 1.", thread_limit);
3477 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00505)
3478 "ThreadLimit of %d not allowed, increasing to 1",
3484 /* you cannot change ThreadLimit across a restart; ignore
3487 if (!retained->first_thread_limit) {
3488 retained->first_thread_limit = thread_limit;
3490 else if (thread_limit != retained->first_thread_limit) {
3491 /* don't need a startup console version here */
3492 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00506)
3493 "changing ThreadLimit to %d from original value of %d "
3494 "not allowed during restart",
3495 thread_limit, retained->first_thread_limit);
3496 thread_limit = retained->first_thread_limit;
3499 if (threads_per_child > thread_limit) {
3501 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00507)
3502 "WARNING: ThreadsPerChild of %d exceeds ThreadLimit "
3503 "of %d threads, decreasing to %d. "
3504 "To increase, please see the ThreadLimit directive.",
3505 threads_per_child, thread_limit, thread_limit);
3507 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00508)
3508 "ThreadsPerChild of %d exceeds ThreadLimit "
3509 "of %d, decreasing to match",
3510 threads_per_child, thread_limit);
3512 threads_per_child = thread_limit;
3514 else if (threads_per_child < 1) {
3516 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00509)
3517 "WARNING: ThreadsPerChild of %d not allowed, "
3518 "increasing to 1.", threads_per_child);
3520 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00510)
3521 "ThreadsPerChild of %d not allowed, increasing to 1",
3524 threads_per_child = 1;
3527 if (max_workers < threads_per_child) {
3529 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00511)
3530 "WARNING: MaxRequestWorkers of %d is less than "
3531 "ThreadsPerChild of %d, increasing to %d. "
3532 "MaxRequestWorkers must be at least as large "
3533 "as the number of threads in a single server.",
3534 max_workers, threads_per_child, threads_per_child);
3536 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00512)
3537 "MaxRequestWorkers of %d is less than ThreadsPerChild "
3538 "of %d, increasing to match",
3539 max_workers, threads_per_child);
3541 max_workers = threads_per_child;
3544 active_daemons_limit = max_workers / threads_per_child;
3546 if (max_workers % threads_per_child) {
3547 int tmp_max_workers = active_daemons_limit * threads_per_child;
3550 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00513)
3551 "WARNING: MaxRequestWorkers of %d is not an integer "
3552 "multiple of ThreadsPerChild of %d, decreasing to nearest "
3553 "multiple %d, for a maximum of %d servers.",
3554 max_workers, threads_per_child, tmp_max_workers,
3555 active_daemons_limit);
3557 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00514)
3558 "MaxRequestWorkers of %d is not an integer multiple "
3559 "of ThreadsPerChild of %d, decreasing to nearest "
3560 "multiple %d", max_workers, threads_per_child,
3563 max_workers = tmp_max_workers;
3566 if (active_daemons_limit > server_limit) {
3568 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00515)
3569 "WARNING: MaxRequestWorkers of %d would require %d servers "
3570 "and would exceed ServerLimit of %d, decreasing to %d. "
3571 "To increase, please see the ServerLimit directive.",
3572 max_workers, active_daemons_limit, server_limit,
3573 server_limit * threads_per_child);
3575 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00516)
3576 "MaxRequestWorkers of %d would require %d servers and "
3577 "exceed ServerLimit of %d, decreasing to %d",
3578 max_workers, active_daemons_limit, server_limit,
3579 server_limit * threads_per_child);
3581 active_daemons_limit = server_limit;
3584 /* ap_daemons_to_start > active_daemons_limit checked in ap_mpm_run() */
3585 if (ap_daemons_to_start < 1) {
3587 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00517)
3588 "WARNING: StartServers of %d not allowed, "
3589 "increasing to 1.", ap_daemons_to_start);
3591 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00518)
3592 "StartServers of %d not allowed, increasing to 1",
3593 ap_daemons_to_start);
3595 ap_daemons_to_start = 1;
3598 if (min_spare_threads < 1) {
3600 ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00519)
3601 "WARNING: MinSpareThreads of %d not allowed, "
3602 "increasing to 1 to avoid almost certain server "
3603 "failure. Please read the documentation.",
3606 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00520)
3607 "MinSpareThreads of %d not allowed, increasing to 1",
3610 min_spare_threads = 1;
3613 /* max_spare_threads < min_spare_threads + threads_per_child
3614 * checked in ap_mpm_run()
3620 static void event_hooks(apr_pool_t * p)
3622 /* Our open_logs hook function must run before the core's, or stderr
3623 * will be redirected to a file, and the messages won't print to the
3626 static const char *const aszSucc[] = { "core.c", NULL };
3629 ap_hook_open_logs(event_open_logs, NULL, aszSucc, APR_HOOK_REALLY_FIRST);
3630 /* we need to set the MPM state before other pre-config hooks use MPM query
3631 * to retrieve it, so register as REALLY_FIRST
3633 ap_hook_pre_config(event_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
3634 ap_hook_post_config(event_post_config, NULL, NULL, APR_HOOK_MIDDLE);
3635 ap_hook_check_config(event_check_config, NULL, NULL, APR_HOOK_MIDDLE);
3636 ap_hook_mpm(event_run, NULL, NULL, APR_HOOK_MIDDLE);
3637 ap_hook_mpm_query(event_query, NULL, NULL, APR_HOOK_MIDDLE);
3638 ap_hook_mpm_register_timed_callback(event_register_timed_callback, NULL, NULL,
3640 ap_hook_pre_read_request(event_pre_read_request, NULL, NULL, APR_HOOK_MIDDLE);
3641 ap_hook_post_read_request(event_post_read_request, NULL, NULL, APR_HOOK_MIDDLE);
3642 ap_hook_mpm_get_name(event_get_name, NULL, NULL, APR_HOOK_MIDDLE);
3644 ap_hook_pre_connection(event_pre_connection, NULL, NULL, APR_HOOK_REALLY_FIRST);
3645 ap_hook_protocol_switch(event_protocol_switch, NULL, NULL, APR_HOOK_REALLY_FIRST);
3648 static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy,
3651 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3656 ap_daemons_to_start = atoi(arg);
3660 static const char *set_min_spare_threads(cmd_parms * cmd, void *dummy,
3663 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3668 min_spare_threads = atoi(arg);
3672 static const char *set_max_spare_threads(cmd_parms * cmd, void *dummy,
3675 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3680 max_spare_threads = atoi(arg);
3684 static const char *set_max_workers(cmd_parms * cmd, void *dummy,
3687 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3691 if (!strcasecmp(cmd->cmd->name, "MaxClients")) {
3692 ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL, APLOGNO(00521)
3693 "MaxClients is deprecated, use MaxRequestWorkers "
3696 max_workers = atoi(arg);
3700 static const char *set_threads_per_child(cmd_parms * cmd, void *dummy,
3703 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3708 threads_per_child = atoi(arg);
3711 static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg)
3713 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3718 server_limit = atoi(arg);
3722 static const char *set_thread_limit(cmd_parms * cmd, void *dummy,
3725 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3730 thread_limit = atoi(arg);
3734 static const char *set_worker_factor(cmd_parms * cmd, void *dummy,
3739 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3744 val = strtod(arg, &endptr);
3746 return "error parsing value";
3749 return "AsyncRequestWorkerFactor argument must be a positive number";
3751 worker_factor = val * WORKER_FACTOR_SCALE;
3752 if (worker_factor == 0)
3758 static const command_rec event_cmds[] = {
3760 AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
3761 "Number of child processes launched at server startup"),
3762 AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF,
3763 "Maximum number of child processes for this run of Apache"),
3764 AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF,
3765 "Minimum number of idle threads, to handle request spikes"),
3766 AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF,
3767 "Maximum number of idle threads"),
3768 AP_INIT_TAKE1("MaxClients", set_max_workers, NULL, RSRC_CONF,
3769 "Deprecated name of MaxRequestWorkers"),
3770 AP_INIT_TAKE1("MaxRequestWorkers", set_max_workers, NULL, RSRC_CONF,
3771 "Maximum number of threads alive at the same time"),
3772 AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF,
3773 "Number of threads each child creates"),
3774 AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF,
3775 "Maximum number of worker threads per child process for this "
3776 "run of Apache - Upper limit for ThreadsPerChild"),
3777 AP_INIT_TAKE1("AsyncRequestWorkerFactor", set_worker_factor, NULL, RSRC_CONF,
3778 "How many additional connects will be accepted per idle "
3780 AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND,
3784 AP_DECLARE_MODULE(mpm_event) = {
3786 NULL, /* hook to run before apache parses args */
3787 NULL, /* create per-directory config structure */
3788 NULL, /* merge per-directory config structures */
3789 NULL, /* create per-server config structure */
3790 NULL, /* merge per-server config structures */
3791 event_cmds, /* command apr_table_t */
3792 event_hooks /* register_hooks */