summaryrefslogtreecommitdiff
path: root/server/mpm
diff options
context:
space:
mode:
Diffstat (limited to 'server/mpm')
-rw-r--r--server/mpm/config.m411
-rw-r--r--server/mpm/event/config.m42
-rw-r--r--server/mpm/event/config3.m42
-rw-r--r--server/mpm/event/event.c177
-rw-r--r--server/mpm/event/pod.c113
-rw-r--r--server/mpm/event/pod.h59
-rw-r--r--server/mpm/winnt/child.c105
-rw-r--r--server/mpm/winnt/mpm_winnt.c2
-rw-r--r--server/mpm/winnt/mpm_winnt.h2
-rw-r--r--server/mpm/worker/config3.m42
-rw-r--r--server/mpm/worker/pod.c113
-rw-r--r--server/mpm/worker/pod.h58
-rw-r--r--server/mpm/worker/worker.c45
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");