diff options
Diffstat (limited to 'server/mpm')
-rw-r--r-- | server/mpm/config.m4 | 11 | ||||
-rw-r--r-- | server/mpm/event/config.m4 | 2 | ||||
-rw-r--r-- | server/mpm/event/config3.m4 | 2 | ||||
-rw-r--r-- | server/mpm/event/event.c | 177 | ||||
-rw-r--r-- | server/mpm/event/pod.c | 113 | ||||
-rw-r--r-- | server/mpm/event/pod.h | 59 | ||||
-rw-r--r-- | server/mpm/winnt/child.c | 105 | ||||
-rw-r--r-- | server/mpm/winnt/mpm_winnt.c | 2 | ||||
-rw-r--r-- | server/mpm/winnt/mpm_winnt.h | 2 | ||||
-rw-r--r-- | server/mpm/worker/config3.m4 | 2 | ||||
-rw-r--r-- | server/mpm/worker/pod.c | 113 | ||||
-rw-r--r-- | server/mpm/worker/pod.h | 58 | ||||
-rw-r--r-- | server/mpm/worker/worker.c | 45 |
13 files changed, 231 insertions, 460 deletions
diff --git a/server/mpm/config.m4 b/server/mpm/config.m4 index 0b263cbc..07118bd9 100644 --- a/server/mpm/config.m4 +++ b/server/mpm/config.m4 @@ -38,6 +38,17 @@ AC_CACHE_CHECK([whether APR supports thread-safe pollsets], [ac_cv_have_threadsa fi ]) +dnl See if APR has skiplist +dnl The base httpd prereq is APR 1.4.x, so we don't have to consider +dnl earlier versions. +case $APR_VERSION in + 1.4*) + apr_has_skiplist=no + ;; + *) + apr_has_skiplist=yes +esac + dnl See if this is a forking platform w.r.t. MPMs case $host in *mingw32* | *os2-emx*) diff --git a/server/mpm/event/config.m4 b/server/mpm/event/config.m4 index 351f1acf..c891c758 100644 --- a/server/mpm/event/config.m4 +++ b/server/mpm/event/config.m4 @@ -7,6 +7,8 @@ elif test $have_threaded_sig_graceful != yes; then AC_MSG_RESULT(no - SIG_GRACEFUL cannot be used with a threaded MPM) elif test $ac_cv_have_threadsafe_pollset != yes; then AC_MSG_RESULT(no - APR_POLLSET_THREADSAFE is not supported) +elif test $apr_has_skiplist != yes; then + AC_MSG_RESULT(no - APR skiplist is not available, need APR 1.5.x or later) else AC_MSG_RESULT(yes) APACHE_MPM_SUPPORTED(event, yes, yes) diff --git a/server/mpm/event/config3.m4 b/server/mpm/event/config3.m4 index e7ec6320..8aa1631f 100644 --- a/server/mpm/event/config3.m4 +++ b/server/mpm/event/config3.m4 @@ -2,6 +2,6 @@ dnl ## XXX - Need a more thorough check of the proper flags to use APACHE_SUBST(MOD_MPM_EVENT_LDADD) -APACHE_MPM_MODULE(event, $enable_mpm_event, event.lo fdqueue.lo pod.lo,[ +APACHE_MPM_MODULE(event, $enable_mpm_event, event.lo fdqueue.lo,[ AC_CHECK_FUNCS(pthread_kill) ], , [\$(MOD_MPM_EVENT_LDADD)]) diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c index c64b08f5..306837db 100644 --- a/server/mpm/event/event.c +++ b/server/mpm/event/event.c @@ -84,7 +84,6 @@ #include "http_core.h" /* for get_remote_host */ #include "http_connection.h" #include "ap_mpm.h" -#include "pod.h" #include "mpm_common.h" #include "ap_listen.h" #include "scoreboard.h" @@ -92,6 +91,7 @@ #include "mpm_default.h" #include "http_vhost.h" #include "unixd.h" +#include "apr_skiplist.h" #include <signal.h> #include <limits.h> /* for INT_MAX */ @@ -321,7 +321,7 @@ static event_retained_data *retained; #define ID_FROM_CHILD_THREAD(c, t) ((c * thread_limit) + t) -static ap_event_pod_t *pod; +static ap_pod_t *pod; /* The event MPM respects a couple of runtime flags that can aid * in debugging. Setting the -DNO_DETACH flag will prevent the root process @@ -790,7 +790,10 @@ static int start_lingering_close_common(event_conn_state_t *cs) apr_atomic_inc32(&lingering_count); apr_thread_mutex_lock(timeout_mutex); TO_QUEUE_APPEND(*q, cs); - cs->pfd.reqevents = APR_POLLIN | APR_POLLHUP | APR_POLLERR; + cs->pfd.reqevents = ( + cs->pub.sense == CONN_SENSE_WANT_WRITE ? APR_POLLOUT : + APR_POLLIN) | APR_POLLHUP | APR_POLLERR; + cs->pub.sense = CONN_SENSE_DEFAULT; rv = apr_pollset_add(event_pollset, &cs->pfd); apr_thread_mutex_unlock(timeout_mutex); if (rv != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rv)) { @@ -938,6 +941,7 @@ static void process_socket(apr_thread_t *thd, apr_pool_t * p, apr_socket_t * soc */ cs->pub.state = CONN_STATE_READ_REQUEST_LINE; + cs->pub.sense = CONN_SENSE_DEFAULT; } else { c = cs->c; @@ -946,9 +950,11 @@ static void process_socket(apr_thread_t *thd, apr_pool_t * p, apr_socket_t * soc } if (c->clogging_input_filters && !c->aborted) { - /* Since we have an input filter which 'cloggs' the input stream, - * like mod_ssl, lets just do the normal read from input filters, - * like the Worker MPM does. + /* Since we have an input filter which 'clogs' the input stream, + * like mod_ssl used to, lets just do the normal read from input + * filters, like the Worker MPM does. Filters that need to write + * where they would otherwise read, or read where they would + * otherwise write, should set the sense appropriately. */ apr_atomic_inc32(&clogged_count); ap_run_process_connection(c); @@ -994,7 +1000,10 @@ read_request: cs->expiration_time = ap_server_conf->timeout + apr_time_now(); apr_thread_mutex_lock(timeout_mutex); TO_QUEUE_APPEND(write_completion_q, cs); - cs->pfd.reqevents = APR_POLLOUT | APR_POLLHUP | APR_POLLERR; + cs->pfd.reqevents = ( + cs->pub.sense == CONN_SENSE_WANT_READ ? APR_POLLIN : + APR_POLLOUT) | APR_POLLHUP | APR_POLLERR; + cs->pub.sense = CONN_SENSE_DEFAULT; rc = apr_pollset_add(event_pollset, &cs->pfd); apr_thread_mutex_unlock(timeout_mutex); return; @@ -1017,8 +1026,6 @@ read_request: return; } else if (cs->pub.state == CONN_STATE_CHECK_REQUEST_LINE_READABLE) { - apr_status_t rc; - /* It greatly simplifies the logic to use a single timeout value here * because the new element can just be added to the end of the list and * it will stay sorted in expiration time sequence. If brand new @@ -1029,6 +1036,7 @@ read_request: */ cs->expiration_time = ap_server_conf->keep_alive_timeout + apr_time_now(); + c->sbh = NULL; apr_thread_mutex_lock(timeout_mutex); TO_QUEUE_APPEND(keepalive_q, cs); @@ -1042,6 +1050,7 @@ read_request: "process_socket: apr_pollset_add failure"); AP_DEBUG_ASSERT(rc == APR_SUCCESS); } + return; } else if (cs->pub.state == CONN_STATE_SUSPENDED) { apr_atomic_inc32(&suspended_count); @@ -1053,7 +1062,6 @@ read_request: * or timeout. */ c->sbh = NULL; - return; } @@ -1217,34 +1225,44 @@ static void get_worker(int *have_idle_worker_p, int blocking, int *all_busy) } } -/* XXXXXX: Convert to skiplist or other better data structure - * (yes, this is VERY VERY VERY VERY BAD) - */ - /* Structures to reuse */ static APR_RING_HEAD(timer_free_ring_t, timer_event_t) timer_free_ring; -/* Active timers */ -static APR_RING_HEAD(timer_ring_t, timer_event_t) timer_ring; -static apr_thread_mutex_t *g_timer_ring_mtx; +static apr_skiplist *timer_skiplist; + +static int indexing_comp(void *a, void *b) +{ + apr_time_t t1 = (apr_time_t) (((timer_event_t *) a)->when); + apr_time_t t2 = (apr_time_t) (((timer_event_t *) b)->when); + AP_DEBUG_ASSERT(t1); + AP_DEBUG_ASSERT(t2); + return ((t1 < t2) ? -1 : ((t1 > t2) ? 1 : 0)); +} + +static int indexing_compk(void *ac, void *b) +{ + apr_time_t *t1 = (apr_time_t *) ac; + apr_time_t t2 = (apr_time_t) (((timer_event_t *) b)->when); + AP_DEBUG_ASSERT(t2); + return ((*t1 < t2) ? -1 : ((*t1 > t2) ? 1 : 0)); +} + +static apr_thread_mutex_t *g_timer_skiplist_mtx; static apr_status_t event_register_timed_callback(apr_time_t t, ap_mpm_callback_fn_t *cbfn, void *baton) { - int inserted = 0; - timer_event_t *ep; timer_event_t *te; /* oh yeah, and make locking smarter/fine grained. */ - apr_thread_mutex_lock(g_timer_ring_mtx); + apr_thread_mutex_lock(g_timer_skiplist_mtx); if (!APR_RING_EMPTY(&timer_free_ring, timer_event_t, link)) { te = APR_RING_FIRST(&timer_free_ring); APR_RING_REMOVE(te, link); } else { - /* XXXXX: lol, pool allocation without a context from any thread.Yeah. Right. MPMs Suck. */ - te = ap_malloc(sizeof(timer_event_t)); + te = apr_skiplist_alloc(timer_skiplist, sizeof(timer_event_t)); APR_RING_ELEM_INIT(te, link); } @@ -1254,27 +1272,14 @@ static apr_status_t event_register_timed_callback(apr_time_t t, te->when = t + apr_time_now(); /* Okay, insert sorted by when.. */ - for (ep = APR_RING_FIRST(&timer_ring); - ep != APR_RING_SENTINEL(&timer_ring, - timer_event_t, link); - ep = APR_RING_NEXT(ep, link)) - { - if (ep->when > te->when) { - inserted = 1; - APR_RING_INSERT_BEFORE(ep, te, link); - break; - } - } - - if (!inserted) { - APR_RING_INSERT_TAIL(&timer_ring, te, timer_event_t, link); - } + apr_skiplist_insert(timer_skiplist, (void *)te); - apr_thread_mutex_unlock(g_timer_ring_mtx); + apr_thread_mutex_unlock(g_timer_skiplist_mtx); return APR_SUCCESS; } + /* * Close socket and clean up if remote closed its end while we were in * lingering close. @@ -1296,7 +1301,7 @@ static void process_lingering_close(event_conn_state_t *cs, const apr_pollfd_t * rv = apr_socket_recv(csd, dummybuf, &nbytes); } while (rv == APR_SUCCESS); - if (!APR_STATUS_IS_EOF(rv)) { + if (APR_STATUS_IS_EAGAIN(rv)) { return; } @@ -1437,9 +1442,9 @@ static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy) } } - apr_thread_mutex_lock(g_timer_ring_mtx); - if (!APR_RING_EMPTY(&timer_ring, timer_event_t, link)) { - te = APR_RING_FIRST(&timer_ring); + apr_thread_mutex_lock(g_timer_skiplist_mtx); + te = apr_skiplist_peek(timer_skiplist); + if (te) { if (te->when > now) { timeout_interval = te->when - now; } @@ -1450,7 +1455,7 @@ static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy) else { timeout_interval = apr_time_from_msec(100); } - apr_thread_mutex_unlock(g_timer_ring_mtx); + apr_thread_mutex_unlock(g_timer_skiplist_mtx); rc = apr_pollset_poll(event_pollset, timeout_interval, &num, &out_pfd); if (rc != APR_SUCCESS) { @@ -1473,21 +1478,19 @@ static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy) } now = apr_time_now(); - apr_thread_mutex_lock(g_timer_ring_mtx); - for (ep = APR_RING_FIRST(&timer_ring); - ep != APR_RING_SENTINEL(&timer_ring, - timer_event_t, link); - ep = APR_RING_FIRST(&timer_ring)) - { + apr_thread_mutex_lock(g_timer_skiplist_mtx); + ep = apr_skiplist_peek(timer_skiplist); + while (ep) { if (ep->when < now + EVENT_FUDGE_FACTOR) { - APR_RING_REMOVE(ep, link); + apr_skiplist_pop(timer_skiplist, NULL); push_timer2worker(ep); } else { break; } + ep = apr_skiplist_peek(timer_skiplist); } - apr_thread_mutex_unlock(g_timer_ring_mtx); + apr_thread_mutex_unlock(g_timer_skiplist_mtx); while (num) { pt = (listener_poll_type *) out_pfd->client_data; @@ -1801,9 +1804,9 @@ static void *APR_THREAD_FUNC worker_thread(apr_thread_t * thd, void *dummy) te->cbfunc(te->baton); { - apr_thread_mutex_lock(g_timer_ring_mtx); + apr_thread_mutex_lock(g_timer_skiplist_mtx); APR_RING_INSERT_TAIL(&timer_free_ring, te, timer_event_t, link); - apr_thread_mutex_unlock(g_timer_ring_mtx); + apr_thread_mutex_unlock(g_timer_skiplist_mtx); } } else { @@ -1877,6 +1880,7 @@ static void *APR_THREAD_FUNC start_threads(apr_thread_t * thd, void *dummy) int loops; int prev_threads_created; int max_recycled_pools = -1; + int good_methods[] = {APR_POLLSET_KQUEUE, APR_POLLSET_PORT, APR_POLLSET_EPOLL}; /* We must create the fd queues before we start up the listener * and worker threads. */ @@ -1915,18 +1919,34 @@ static void *APR_THREAD_FUNC start_threads(apr_thread_t * thd, void *dummy) } /* Create the main pollset */ - rv = apr_pollset_create(&event_pollset, - threads_per_child, /* XXX don't we need more, to handle + for (i = 0; i < sizeof(good_methods) / sizeof(void*); i++) { + rv = apr_pollset_create_ex(&event_pollset, + threads_per_child*2, /* XXX don't we need more, to handle * connections in K-A or lingering * close? */ - pchild, APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY); + pchild, APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY | APR_POLLSET_NODEFAULT, + good_methods[i]); + if (rv == APR_SUCCESS) { + break; + } + } + if (rv != APR_SUCCESS) { + rv = apr_pollset_create(&event_pollset, + threads_per_child*2, /* XXX don't we need more, to handle + * connections in K-A or lingering + * close? + */ + pchild, APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY); + } if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, "apr_pollset_create with Thread Safety failed."); clean_child_exit(APEXIT_CHILDFATAL); } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02471) + "start_threads: Using %s", apr_pollset_method_name(event_pollset)); worker_sockets = apr_pcalloc(pchild, threads_per_child * sizeof(apr_socket_t *)); @@ -2087,9 +2107,10 @@ static void child_main(int child_num_arg) clean_child_exit(APEXIT_CHILDFATAL); } - apr_thread_mutex_create(&g_timer_ring_mtx, APR_THREAD_MUTEX_DEFAULT, pchild); + apr_thread_mutex_create(&g_timer_skiplist_mtx, APR_THREAD_MUTEX_DEFAULT, pchild); APR_RING_INIT(&timer_free_ring, timer_event_t, link); - APR_RING_INIT(&timer_ring, timer_event_t, link); + apr_skiplist_init(&timer_skiplist, pchild); + apr_skiplist_set_compare(timer_skiplist, indexing_comp, indexing_compk); ap_run_child_init(pchild, ap_server_conf); /* done with init critical section */ @@ -2188,25 +2209,25 @@ static void child_main(int child_num_arg) apr_signal(SIGTERM, dummy_signal_handler); /* Watch for any messages from the parent over the POD */ while (1) { - rv = ap_event_pod_check(pod); - if (rv == AP_NORESTART) { + rv = ap_mpm_podx_check(pod); + if (rv == AP_MPM_PODX_NORESTART) { /* see if termination was triggered while we slept */ switch (terminate_mode) { case ST_GRACEFUL: - rv = AP_GRACEFUL; + rv = AP_MPM_PODX_GRACEFUL; break; case ST_UNGRACEFUL: - rv = AP_RESTART; + rv = AP_MPM_PODX_RESTART; break; } } - if (rv == AP_GRACEFUL || rv == AP_RESTART) { + if (rv == AP_MPM_PODX_GRACEFUL || rv == AP_MPM_PODX_RESTART) { /* make sure the start thread has finished; * signal_threads() and join_workers depend on that */ join_start_thread(start_thread_id); signal_threads(rv == - AP_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL); + AP_MPM_PODX_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL); break; } } @@ -2435,7 +2456,7 @@ static void perform_idle_server_maintenance(void) if (idle_thread_count > max_spare_threads) { /* Kill off one child */ - ap_event_pod_signal(pod, TRUE); + ap_mpm_podx_signal(pod, AP_MPM_PODX_GRACEFUL); retained->idle_spawn_rate = 1; } else if (idle_thread_count < min_spare_threads) { @@ -2666,7 +2687,7 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s) /* Time to shut down: * Kill child processes, tell them to call child_exit, etc... */ - ap_event_pod_killpg(pod, ap_daemons_limit, FALSE); + ap_mpm_podx_killpg(pod, ap_daemons_limit, AP_MPM_PODX_RESTART); ap_reclaim_child_processes(1, /* Start with SIGTERM */ event_note_child_killed); @@ -2687,7 +2708,7 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s) /* Close our listeners, and then ask our children to do same */ ap_close_listeners(); - ap_event_pod_killpg(pod, ap_daemons_limit, TRUE); + ap_mpm_podx_killpg(pod, ap_daemons_limit, AP_MPM_PODX_GRACEFUL); ap_relieve_child_processes(event_note_child_killed); if (!child_fatal) { @@ -2727,7 +2748,7 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s) * way, try and make sure that all of our processes are * really dead. */ - ap_event_pod_killpg(pod, ap_daemons_limit, FALSE); + ap_mpm_podx_killpg(pod, ap_daemons_limit, AP_MPM_PODX_RESTART); ap_reclaim_child_processes(1, event_note_child_killed); return DONE; @@ -2753,7 +2774,7 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s) AP_SIG_GRACEFUL_STRING " received. Doing graceful restart"); /* wake up the children...time to die. But we'll have more soon */ - ap_event_pod_killpg(pod, ap_daemons_limit, TRUE); + ap_mpm_podx_killpg(pod, ap_daemons_limit, AP_MPM_PODX_GRACEFUL); /* This is mostly for debugging... so that we know what is still @@ -2766,7 +2787,7 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s) * and a SIGHUP, we may as well use the same signal, because some user * pthreads are stealing signals from us left and right. */ - ap_event_pod_killpg(pod, ap_daemons_limit, FALSE); + ap_mpm_podx_killpg(pod, ap_daemons_limit, AP_MPM_PODX_RESTART); ap_reclaim_child_processes(1, /* Start with SIGTERM */ event_note_child_killed); @@ -2803,13 +2824,15 @@ static int event_open_logs(apr_pool_t * p, apr_pool_t * plog, } if (!one_process) { - if ((rv = ap_event_pod_open(pconf, &pod))) { + if ((rv = ap_mpm_podx_open(pconf, &pod))) { ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv, (startup ? NULL : s), "could not open pipe-of-death"); return DONE; } } + /* for skiplist */ + srand((unsigned int)apr_time_now()); return OK; } @@ -2843,6 +2866,18 @@ static int event_pre_config(apr_pool_t * pconf, apr_pool_t * plog, } ++retained->module_loads; if (retained->module_loads == 2) { + int i; + static apr_uint32_t foo = 0; + + apr_atomic_inc32(&foo); + apr_atomic_dec32(&foo); + apr_atomic_dec32(&foo); + i = apr_atomic_dec32(&foo); + if (i >= 0) { + ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, APLOGNO(02405) + "atomics not working as expected"); + return HTTP_INTERNAL_SERVER_ERROR; + } rv = apr_pollset_create(&event_pollset, 1, plog, APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY); if (rv != APR_SUCCESS) { diff --git a/server/mpm/event/pod.c b/server/mpm/event/pod.c deleted file mode 100644 index 5deed8ba..00000000 --- a/server/mpm/event/pod.c +++ /dev/null @@ -1,113 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "pod.h" - -#include "apr_portable.h" - -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif - -APLOG_USE_MODULE(mpm_event); - -AP_DECLARE(apr_status_t) ap_event_pod_open(apr_pool_t * p, ap_event_pod_t ** pod) -{ - apr_status_t rv; - - *pod = apr_palloc(p, sizeof(**pod)); - rv = apr_file_pipe_create(&((*pod)->pod_in), &((*pod)->pod_out), p); - if (rv != APR_SUCCESS) { - return rv; - } -/* - apr_file_pipe_timeout_set((*pod)->pod_in, 0); -*/ - (*pod)->p = p; - - /* close these before exec. */ - apr_file_inherit_unset((*pod)->pod_in); - apr_file_inherit_unset((*pod)->pod_out); - - return APR_SUCCESS; -} - -AP_DECLARE(int) ap_event_pod_check(ap_event_pod_t * pod) -{ - char c; - apr_os_file_t fd; - int rc; - - /* we need to surface EINTR so we'll have to grab the - * native file descriptor and do the OS read() ourselves - */ - apr_os_file_get(&fd, pod->pod_in); - rc = read(fd, &c, 1); - if (rc == 1) { - switch (c) { - case RESTART_CHAR: - return AP_RESTART; - case GRACEFUL_CHAR: - return AP_GRACEFUL; - } - } - return AP_NORESTART; -} - -AP_DECLARE(apr_status_t) ap_event_pod_close(ap_event_pod_t * pod) -{ - apr_status_t rv; - - rv = apr_file_close(pod->pod_out); - if (rv != APR_SUCCESS) { - return rv; - } - - rv = apr_file_close(pod->pod_in); - if (rv != APR_SUCCESS) { - return rv; - } - return rv; -} - -static apr_status_t pod_signal_internal(ap_event_pod_t * pod, int graceful) -{ - apr_status_t rv; - char char_of_death = graceful ? GRACEFUL_CHAR : RESTART_CHAR; - apr_size_t one = 1; - - rv = apr_file_write(pod->pod_out, &char_of_death, &one); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, APLOGNO(00522) - "write pipe_of_death"); - } - return rv; -} - -AP_DECLARE(apr_status_t) ap_event_pod_signal(ap_event_pod_t * pod, int graceful) -{ - return pod_signal_internal(pod, graceful); -} - -AP_DECLARE(void) ap_event_pod_killpg(ap_event_pod_t * pod, int num, int graceful) -{ - int i; - apr_status_t rv = APR_SUCCESS; - - for (i = 0; i < num && rv == APR_SUCCESS; i++) { - rv = pod_signal_internal(pod, graceful); - } -} diff --git a/server/mpm/event/pod.h b/server/mpm/event/pod.h deleted file mode 100644 index 861e4d99..00000000 --- a/server/mpm/event/pod.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file event/pod.h - * @brief pod definitions - * - * @addtogroup APACHE_MPM_EVENT - * @{ - */ - -#include "apr.h" -#include "apr_strings.h" -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#include "httpd.h" -#include "http_config.h" -#include "http_log.h" -#include "http_main.h" -#include "mpm_common.h" -#include "ap_mpm.h" -#include "ap_listen.h" -#include "mpm_default.h" - -#define RESTART_CHAR '$' -#define GRACEFUL_CHAR '!' - -#define AP_RESTART 0 -#define AP_GRACEFUL 1 - -typedef struct ap_event_pod_t ap_event_pod_t; - -struct ap_event_pod_t -{ - apr_file_t *pod_in; - apr_file_t *pod_out; - apr_pool_t *p; -}; - -AP_DECLARE(apr_status_t) ap_event_pod_open(apr_pool_t * p, ap_event_pod_t ** pod); -AP_DECLARE(int) ap_event_pod_check(ap_event_pod_t * pod); -AP_DECLARE(apr_status_t) ap_event_pod_close(ap_event_pod_t * pod); -AP_DECLARE(apr_status_t) ap_event_pod_signal(ap_event_pod_t * pod, int graceful); -AP_DECLARE(void) ap_event_pod_killpg(ap_event_pod_t * pod, int num, int graceful); -/** @} */ diff --git a/server/mpm/winnt/child.c b/server/mpm/winnt/child.c index 7983851a..c9168b08 100644 --- a/server/mpm/winnt/child.c +++ b/server/mpm/winnt/child.c @@ -45,7 +45,22 @@ #ifdef __MINGW32__ #include <mswsock.h> -#endif + +#ifndef WSAID_ACCEPTEX +#define WSAID_ACCEPTEX \ + {0xb5367df1, 0xcbac, 0x11cf, {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}} +typedef BOOL (WINAPI *LPFN_ACCEPTEX)(SOCKET, SOCKET, PVOID, DWORD, DWORD, DWORD, LPDWORD, LPOVERLAPPED); +#endif /* WSAID_ACCEPTEX */ + +#ifndef WSAID_GETACCEPTEXSOCKADDRS +#define WSAID_GETACCEPTEXSOCKADDRS \ + {0xb5367df2, 0xcbac, 0x11cf, {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}} +typedef VOID (WINAPI *LPFN_GETACCEPTEXSOCKADDRS)(PVOID, DWORD, DWORD, DWORD, + struct sockaddr **, LPINT, + struct sockaddr **, LPINT); +#endif /* WSAID_GETACCEPTEXSOCKADDRS */ + +#endif /* __MINGW32__ */ /* * The Windows MPM uses a queue of completion contexts that it passes @@ -281,6 +296,10 @@ static unsigned int __stdcall winnt_accept(void *lr_) winnt_conn_ctx_t *context = NULL; DWORD BytesRead; SOCKET nlsd; + LPFN_ACCEPTEX lpfnAcceptEx = NULL; + LPFN_GETACCEPTEXSOCKADDRS lpfnGetAcceptExSockaddrs = NULL; + GUID GuidAcceptEx = WSAID_ACCEPTEX; + GUID GuidGetAcceptExSockaddrs = WSAID_GETACCEPTEXSOCKADDRS; core_server_config *core_sconf; const char *accf_name; int rv; @@ -296,7 +315,15 @@ static unsigned int __stdcall winnt_accept(void *lr_) core_sconf = ap_get_core_module_config(ap_server_conf->module_config); accf_name = apr_table_get(core_sconf->accf_map, lr->protocol); - if (strcmp(accf_name, "data") == 0) + if (!accf_name) { + accf = 0; + accf_name = "none"; + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf, + APLOGNO(02531) "winnt_accept: Listen protocol '%s' has " + "no known accept filter. Using 'none' instead", + lr->protocol); + } + else if (strcmp(accf_name, "data") == 0) accf = 2; else if (strcmp(accf_name, "connect") == 0) accf = 1; @@ -325,6 +352,24 @@ static unsigned int __stdcall winnt_accept(void *lr_) if (accf > 0) /* 'data' or 'connect' */ { + if (WSAIoctl(nlsd, SIO_GET_EXTENSION_FUNCTION_POINTER, + &GuidAcceptEx, sizeof GuidAcceptEx, + &lpfnAcceptEx, sizeof lpfnAcceptEx, + &BytesRead, NULL, NULL) == SOCKET_ERROR) { + ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_netos_error(), + ap_server_conf, APLOGNO(02322) + "winnt_accept: failed to retrieve AcceptEx, try 'AcceptFilter none'"); + return 1; + } + if (WSAIoctl(nlsd, SIO_GET_EXTENSION_FUNCTION_POINTER, + &GuidGetAcceptExSockaddrs, sizeof GuidGetAcceptExSockaddrs, + &lpfnGetAcceptExSockaddrs, sizeof lpfnGetAcceptExSockaddrs, + &BytesRead, NULL, NULL) == SOCKET_ERROR) { + ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_netos_error(), + ap_server_conf, APLOGNO(02323) + "winnt_accept: failed to retrieve GetAcceptExSockaddrs, try 'AcceptFilter none'"); + return 1; + } /* first, high priority event is an already accepted connection */ events[1] = exit_event; events[2] = max_requests_per_child_event; @@ -421,9 +466,9 @@ reinit: /* target of data or connect upon too many AcceptEx failures */ /* AcceptEx on the completion context. The completion context will be * signaled when a connection is accepted. */ - if (!AcceptEx(nlsd, context->accept_socket, buf, len, - PADDED_ADDR_SIZE, PADDED_ADDR_SIZE, &BytesRead, - &context->overlapped)) { + if (!lpfnAcceptEx(nlsd, context->accept_socket, buf, len, + PADDED_ADDR_SIZE, PADDED_ADDR_SIZE, &BytesRead, + &context->overlapped)) { rv = apr_get_netos_error(); if ((rv == APR_FROM_OS_ERROR(WSAECONNRESET)) || (rv == APR_FROM_OS_ERROR(WSAEACCES))) { @@ -540,9 +585,9 @@ reinit: /* target of data or connect upon too many AcceptEx failures */ /* Get the local & remote address * TODO; error check */ - GetAcceptExSockaddrs(buf, len, PADDED_ADDR_SIZE, PADDED_ADDR_SIZE, - &context->sa_server, &context->sa_server_len, - &context->sa_client, &context->sa_client_len); + lpfnGetAcceptExSockaddrs(buf, len, PADDED_ADDR_SIZE, PADDED_ADDR_SIZE, + &context->sa_server, &context->sa_server_len, + &context->sa_client, &context->sa_client_len); /* For 'data', craft a bucket for our data result * and pass to worker_main as context->overlapped.Pointer @@ -801,12 +846,12 @@ static DWORD __stdcall worker_main(void *thread_num_val) context->sock, thread_num, sbh, context->ba); - if (!c) - { + if (!c) { /* ap_run_create_connection closes the socket on failure */ context->accept_socket = INVALID_SOCKET; - if (e) + if (e) { apr_bucket_free(e); + } continue; } @@ -824,17 +869,14 @@ static DWORD __stdcall worker_main(void *thread_num_val) c->aborted = 1; } - if (e && c->aborted) - { + if (e && c->aborted) { apr_bucket_free(e); } - else - { + else { ap_set_module_config(c->conn_config, &mpm_winnt_module, context); } - if (!c->aborted) - { + if (!c->aborted) { ap_run_process_connection(c); apr_socket_opt_get(context->sock, APR_SO_DISCONNECTED, @@ -908,12 +950,12 @@ static void create_listener_thread(void) } -void child_main(apr_pool_t *pconf) +void child_main(apr_pool_t *pconf, DWORD parent_pid) { apr_status_t status; apr_hash_t *ht; ap_listen_rec *lr; - HANDLE child_events[2]; + HANDLE child_events[3]; HANDLE *child_handles; int listener_started = 0; int threads_created = 0; @@ -923,6 +965,7 @@ void child_main(apr_pool_t *pconf) DWORD tid; int rv; int i; + int num_events; apr_pool_create(&pchild, pconf); apr_pool_tag(pchild, "pchild"); @@ -940,6 +983,16 @@ void child_main(apr_pool_t *pconf) child_events[0] = exit_event; child_events[1] = max_requests_per_child_event; + if (parent_pid != my_pid) { + child_events[2] = OpenProcess(SYNCHRONIZE, FALSE, parent_pid); + num_events = 3; + } + else { + /* presumably -DONE_PROCESS */ + child_events[2] = NULL; + num_events = 2; + } + /* * Wait until we have permission to start accepting connections. * start_mutex is used to ensure that only one child ever @@ -1056,10 +1109,10 @@ void child_main(apr_pool_t *pconf) */ while (1) { #if !APR_HAS_OTHER_CHILD - rv = WaitForMultipleObjects(2, (HANDLE *)child_events, FALSE, INFINITE); + rv = WaitForMultipleObjects(num_events, (HANDLE *)child_events, FALSE, INFINITE); cld = rv - WAIT_OBJECT_0; #else - rv = WaitForMultipleObjects(2, (HANDLE *)child_events, FALSE, 1000); + rv = WaitForMultipleObjects(num_events, (HANDLE *)child_events, FALSE, 1000); cld = rv - WAIT_OBJECT_0; if (rv == WAIT_TIMEOUT) { apr_proc_other_child_refresh_all(APR_OC_REASON_RUNNING); @@ -1080,6 +1133,13 @@ void child_main(apr_pool_t *pconf) "ending."); break; } + else if (cld == 2) { + /* The parent is dead. Shutdown the child process. */ + ap_log_error(APLOG_MARK, APLOG_CRIT, 0, ap_server_conf, APLOGNO(02538) + "Child: Parent process exited abruptly. Child process " + "is ending"); + break; + } else { /* MaxConnectionsPerChild event set by the worker threads. * Signal the parent to restart @@ -1245,6 +1305,9 @@ void child_main(apr_pool_t *pconf) apr_pool_destroy(pchild); CloseHandle(exit_event); + if (child_events[2] != NULL) { + CloseHandle(child_events[2]); + } } #endif /* def WIN32 */ diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c index 4e3b23ce..957af639 100644 --- a/server/mpm/winnt/mpm_winnt.c +++ b/server/mpm/winnt/mpm_winnt.c @@ -1708,7 +1708,7 @@ static int winnt_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s ) ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, ap_server_conf, APLOGNO(00453) "Child process is running"); - child_main(pconf); + child_main(pconf, parent_pid); ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, ap_server_conf, APLOGNO(00454) "Child process is exiting"); diff --git a/server/mpm/winnt/mpm_winnt.h b/server/mpm/winnt/mpm_winnt.h index 7452f9fb..8fb595b4 100644 --- a/server/mpm/winnt/mpm_winnt.h +++ b/server/mpm/winnt/mpm_winnt.h @@ -90,7 +90,7 @@ AP_DECLARE(void) ap_signal_parent(ap_signal_parent_e type); void hold_console_open_on_error(void); /* From child.c: */ -void child_main(apr_pool_t *pconf); +void child_main(apr_pool_t *pconf, DWORD parent_pid); apr_status_t winnt_insert_network_bucket(conn_rec *c, apr_bucket_brigade *bb, apr_socket_t *socket); diff --git a/server/mpm/worker/config3.m4 b/server/mpm/worker/config3.m4 index dc2bccb5..c28b73bf 100644 --- a/server/mpm/worker/config3.m4 +++ b/server/mpm/worker/config3.m4 @@ -1,5 +1,5 @@ dnl ## XXX - Need a more thorough check of the proper flags to use -APACHE_MPM_MODULE(worker, $enable_mpm_worker, worker.lo fdqueue.lo pod.lo,[ +APACHE_MPM_MODULE(worker, $enable_mpm_worker, worker.lo fdqueue.lo,[ AC_CHECK_FUNCS(pthread_kill) ]) diff --git a/server/mpm/worker/pod.c b/server/mpm/worker/pod.c deleted file mode 100644 index 86f7b39d..00000000 --- a/server/mpm/worker/pod.c +++ /dev/null @@ -1,113 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr_portable.h" -#include "pod.h" - -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif - -APLOG_USE_MODULE(mpm_worker); - -AP_DECLARE(apr_status_t) ap_worker_pod_open(apr_pool_t *p, ap_worker_pod_t **pod) -{ - apr_status_t rv; - - *pod = apr_palloc(p, sizeof(**pod)); - rv = apr_file_pipe_create(&((*pod)->pod_in), &((*pod)->pod_out), p); - if (rv != APR_SUCCESS) { - return rv; - } -/* - apr_file_pipe_timeout_set((*pod)->pod_in, 0); -*/ - (*pod)->p = p; - - /* close these before exec. */ - apr_file_inherit_unset((*pod)->pod_in); - apr_file_inherit_unset((*pod)->pod_out); - - return APR_SUCCESS; -} - -AP_DECLARE(int) ap_worker_pod_check(ap_worker_pod_t *pod) -{ - char c; - apr_os_file_t fd; - int rc; - - /* we need to surface EINTR so we'll have to grab the - * native file descriptor and do the OS read() ourselves - */ - apr_os_file_get(&fd, pod->pod_in); - rc = read(fd, &c, 1); - if (rc == 1) { - switch(c) { - case RESTART_CHAR: - return AP_RESTART; - case GRACEFUL_CHAR: - return AP_GRACEFUL; - } - } - return AP_NORESTART; -} - -AP_DECLARE(apr_status_t) ap_worker_pod_close(ap_worker_pod_t *pod) -{ - apr_status_t rv; - - rv = apr_file_close(pod->pod_out); - if (rv != APR_SUCCESS) { - return rv; - } - - rv = apr_file_close(pod->pod_in); - if (rv != APR_SUCCESS) { - return rv; - } - return rv; -} - -static apr_status_t pod_signal_internal(ap_worker_pod_t *pod, int graceful) -{ - apr_status_t rv; - char char_of_death = graceful ? GRACEFUL_CHAR : RESTART_CHAR; - apr_size_t one = 1; - - rv = apr_file_write(pod->pod_out, &char_of_death, &one); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, APLOGNO(00325) - "write pipe_of_death"); - } - return rv; -} - -AP_DECLARE(apr_status_t) ap_worker_pod_signal(ap_worker_pod_t *pod, int graceful) -{ - return pod_signal_internal(pod, graceful); -} - -AP_DECLARE(void) ap_worker_pod_killpg(ap_worker_pod_t *pod, int num, int graceful) -{ - int i; - apr_status_t rv = APR_SUCCESS; - - for (i = 0; i < num && rv == APR_SUCCESS; i++) { - rv = pod_signal_internal(pod, graceful); - } -} - diff --git a/server/mpm/worker/pod.h b/server/mpm/worker/pod.h deleted file mode 100644 index ccb9cf9d..00000000 --- a/server/mpm/worker/pod.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file worker/pod.h - * @brief Worker MPM Pipe of Death - * - * @addtogroup APACHE_MPM_WORKER - * @{ - */ - -#include "apr.h" -#include "apr_strings.h" -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#include "httpd.h" -#include "http_config.h" -#include "http_log.h" -#include "http_main.h" -#include "mpm_common.h" -#include "ap_mpm.h" -#include "ap_listen.h" -#include "mpm_default.h" - -#define RESTART_CHAR '$' -#define GRACEFUL_CHAR '!' - -#define AP_RESTART 0 -#define AP_GRACEFUL 1 - -typedef struct ap_worker_pod_t ap_worker_pod_t; - -struct ap_worker_pod_t { - apr_file_t *pod_in; - apr_file_t *pod_out; - apr_pool_t *p; -}; - -AP_DECLARE(apr_status_t) ap_worker_pod_open(apr_pool_t *p, ap_worker_pod_t **pod); -AP_DECLARE(int) ap_worker_pod_check(ap_worker_pod_t *pod); -AP_DECLARE(apr_status_t) ap_worker_pod_close(ap_worker_pod_t *pod); -AP_DECLARE(apr_status_t) ap_worker_pod_signal(ap_worker_pod_t *pod, int graceful); -AP_DECLARE(void) ap_worker_pod_killpg(ap_worker_pod_t *pod, int num, int graceful); -/** @} */ diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c index 4d7a92a7..85b7adb0 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -58,7 +58,6 @@ #include "http_core.h" /* for get_remote_host */ #include "http_connection.h" #include "ap_mpm.h" -#include "pod.h" #include "mpm_common.h" #include "ap_listen.h" #include "scoreboard.h" @@ -189,7 +188,7 @@ typedef struct { #define ID_FROM_CHILD_THREAD(c, t) ((c * thread_limit) + t) -static ap_worker_pod_t *pod; +static ap_pod_t *pod; /* The worker MPM respects a couple of runtime flags that can aid * in debugging. Setting the -DNO_DETACH flag will prevent the root process @@ -1130,7 +1129,8 @@ static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy) return NULL; } -static void join_workers(apr_thread_t *listener, apr_thread_t **threads) +static void join_workers(apr_thread_t *listener, apr_thread_t **threads, + int mode) { int i; apr_status_t rv, thread_rv; @@ -1174,12 +1174,14 @@ static void join_workers(apr_thread_t *listener, apr_thread_t **threads) for (i = 0; i < threads_per_child; i++) { if (threads[i]) { /* if we ever created this thread */ + if (mode != ST_GRACEFUL) { #ifdef HAVE_PTHREAD_KILL - apr_os_thread_t *worker_os_thread; + apr_os_thread_t *worker_os_thread; - apr_os_thread_get(&worker_os_thread, threads[i]); - pthread_kill(*worker_os_thread, WORKER_SIGNAL); + apr_os_thread_get(&worker_os_thread, threads[i]); + pthread_kill(*worker_os_thread, WORKER_SIGNAL); #endif + } rv = apr_thread_join(&thread_rv, threads[i]); if (rv != APR_SUCCESS) { @@ -1325,7 +1327,7 @@ static void child_main(int child_num_arg) * If the worker hasn't exited, then this blocks until * they have (then cleans up). */ - join_workers(ts->listener, threads); + join_workers(ts->listener, threads, ST_UNGRACEFUL); } else { /* !one_process */ /* remove SIGTERM from the set of blocked signals... if one of @@ -1336,24 +1338,24 @@ static void child_main(int child_num_arg) apr_signal(SIGTERM, dummy_signal_handler); /* Watch for any messages from the parent over the POD */ while (1) { - rv = ap_worker_pod_check(pod); - if (rv == AP_NORESTART) { + rv = ap_mpm_podx_check(pod); + if (rv == AP_MPM_PODX_NORESTART) { /* see if termination was triggered while we slept */ switch(terminate_mode) { case ST_GRACEFUL: - rv = AP_GRACEFUL; + rv = AP_MPM_PODX_GRACEFUL; break; case ST_UNGRACEFUL: - rv = AP_RESTART; + rv = AP_MPM_PODX_RESTART; break; } } - if (rv == AP_GRACEFUL || rv == AP_RESTART) { + if (rv == AP_MPM_PODX_GRACEFUL || rv == AP_MPM_PODX_RESTART) { /* make sure the start thread has finished; * signal_threads() and join_workers depend on that */ join_start_thread(start_thread_id); - signal_threads(rv == AP_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL); + signal_threads(rv == AP_MPM_PODX_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL); break; } } @@ -1365,7 +1367,8 @@ static void child_main(int child_num_arg) * If the worker hasn't exited, then this blocks until * they have (then cleans up). */ - join_workers(ts->listener, threads); + join_workers(ts->listener, threads, + rv == AP_MPM_PODX_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL); } free(threads); @@ -1578,7 +1581,7 @@ static void perform_idle_server_maintenance(void) if (idle_thread_count > max_spare_threads) { /* Kill off one child */ - ap_worker_pod_signal(pod, TRUE); + ap_mpm_podx_signal(pod, AP_MPM_PODX_GRACEFUL); retained->idle_spawn_rate = 1; } else if (idle_thread_count < min_spare_threads) { @@ -1833,7 +1836,7 @@ static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) /* Time to shut down: * Kill child processes, tell them to call child_exit, etc... */ - ap_worker_pod_killpg(pod, ap_daemons_limit, FALSE); + ap_mpm_podx_killpg(pod, ap_daemons_limit, AP_MPM_PODX_RESTART); ap_reclaim_child_processes(1, /* Start with SIGTERM */ worker_note_child_killed); @@ -1854,7 +1857,7 @@ static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) /* Close our listeners, and then ask our children to do same */ ap_close_listeners(); - ap_worker_pod_killpg(pod, ap_daemons_limit, TRUE); + ap_mpm_podx_killpg(pod, ap_daemons_limit, AP_MPM_PODX_GRACEFUL); ap_relieve_child_processes(worker_note_child_killed); if (!child_fatal) { @@ -1894,7 +1897,7 @@ static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) * way, try and make sure that all of our processes are * really dead. */ - ap_worker_pod_killpg(pod, ap_daemons_limit, FALSE); + ap_mpm_podx_killpg(pod, ap_daemons_limit, AP_MPM_PODX_RESTART); ap_reclaim_child_processes(1, worker_note_child_killed); return DONE; @@ -1919,7 +1922,7 @@ static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00297) AP_SIG_GRACEFUL_STRING " received. Doing graceful restart"); /* wake up the children...time to die. But we'll have more soon */ - ap_worker_pod_killpg(pod, ap_daemons_limit, TRUE); + ap_mpm_podx_killpg(pod, ap_daemons_limit, AP_MPM_PODX_GRACEFUL); /* This is mostly for debugging... so that we know what is still @@ -1932,7 +1935,7 @@ static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) * and a SIGHUP, we may as well use the same signal, because some user * pthreads are stealing signals from us left and right. */ - ap_worker_pod_killpg(pod, ap_daemons_limit, FALSE); + ap_mpm_podx_killpg(pod, ap_daemons_limit, AP_MPM_PODX_RESTART); ap_reclaim_child_processes(1, /* Start with SIGTERM */ worker_note_child_killed); @@ -1968,7 +1971,7 @@ static int worker_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, } if (!one_process) { - if ((rv = ap_worker_pod_open(pconf, &pod))) { + if ((rv = ap_mpm_podx_open(pconf, &pod))) { ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv, (startup ? NULL : s), "could not open pipe-of-death"); |