diff options
-rw-r--r-- | docs/log-message-tags/next-number | 2 | ||||
-rw-r--r-- | include/mpm_common.h | 44 | ||||
-rw-r--r-- | server/mpm/event/config3.m4 | 2 | ||||
-rw-r--r-- | server/mpm/event/event.c | 28 | ||||
-rw-r--r-- | server/mpm/event/pod.c | 113 | ||||
-rw-r--r-- | server/mpm/event/pod.h | 59 | ||||
-rw-r--r-- | server/mpm/eventopt/config3.m4 | 2 | ||||
-rw-r--r-- | server/mpm/eventopt/eventopt.c | 28 | ||||
-rw-r--r-- | server/mpm/eventopt/pod.c | 113 | ||||
-rw-r--r-- | server/mpm/eventopt/pod.h | 59 | ||||
-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 | 26 | ||||
-rw-r--r-- | server/mpm_unix.c | 101 |
15 files changed, 190 insertions, 560 deletions
diff --git a/docs/log-message-tags/next-number b/docs/log-message-tags/next-number index 1475ea9019..075c4f664b 100644 --- a/docs/log-message-tags/next-number +++ b/docs/log-message-tags/next-number @@ -1 +1 @@ -2404 +2405 diff --git a/include/mpm_common.h b/include/mpm_common.h index 0a98d7009e..bfcc98427a 100644 --- a/include/mpm_common.h +++ b/include/mpm_common.h @@ -278,6 +278,50 @@ AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod); */ AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t *pod, int num); + +#define AP_MPM_PODX_RESTART_CHAR '$' +#define AP_MPM_PODX_GRACEFUL_CHAR '!' + +typedef enum { AP_MPM_PODX_NORESTART, AP_MPM_PODX_RESTART, AP_MPM_PODX_GRACEFUL } ap_podx_restart_t; + +/** + * Open the extended pipe-of-death. + * @param p The pool to use for allocating the pipe + * @param pod the pipe-of-death that is created. + */ +AP_DECLARE(apr_status_t) ap_mpm_podx_open(apr_pool_t *p, ap_pod_t **pod); + +/** + * Check the extended pipe to determine if the process has been signalled to die. + */ +AP_DECLARE(int) ap_mpm_podx_check(ap_pod_t *pod); + +/** + * Close the pipe-of-death + * + * @param extended pod the pipe-of-death to close. + */ +AP_DECLARE(apr_status_t) ap_mpm_podx_close(ap_pod_t *pod); + +/** + * Write data to the extended pipe-of-death, signalling that one child process + * should die. + * @param pod the pipe-of-death to write to. + * @param graceful restart-type + */ +AP_DECLARE(apr_status_t) ap_mpm_podx_signal(ap_pod_t *pod, + ap_podx_restart_t graceful); + +/** + * Write data to the extended pipe-of-death, signalling that all child process + * should die. + * @param pod The pipe-of-death to write to. + * @param num The number of child processes to kill + * @param graceful restart-type + */ +AP_DECLARE(void) ap_mpm_podx_killpg(ap_pod_t *pod, int num, + ap_podx_restart_t graceful); + #endif /* !WIN32 || DOXYGEN */ /** diff --git a/server/mpm/event/config3.m4 b/server/mpm/event/config3.m4 index abce9a4f2a..e15f235314 100644 --- a/server/mpm/event/config3.m4 +++ b/server/mpm/event/config3.m4 @@ -8,7 +8,7 @@ if test "$ac_cv_serf" = yes ; then fi 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 2a7052c988..9d782febfc 100644 --- a/server/mpm/event/event.c +++ b/server/mpm/event/event.c @@ -338,7 +338,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 @@ -2257,25 +2257,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; } } @@ -2504,7 +2504,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) { @@ -2735,7 +2735,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); @@ -2756,7 +2756,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) { @@ -2796,7 +2796,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; @@ -2822,7 +2822,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 @@ -2835,7 +2835,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); @@ -2872,7 +2872,7 @@ 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"); diff --git a/server/mpm/event/pod.c b/server/mpm/event/pod.c deleted file mode 100644 index 5deed8baa9..0000000000 --- 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 861e4d9957..0000000000 --- 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/eventopt/config3.m4 b/server/mpm/eventopt/config3.m4 index dd05deba33..7c2aec061c 100644 --- a/server/mpm/eventopt/config3.m4 +++ b/server/mpm/eventopt/config3.m4 @@ -6,6 +6,6 @@ if test "$ac_cv_serf" = yes ; then fi APACHE_SUBST(MOD_MPM_EVENTOPT_LDADD) -APACHE_MPM_MODULE(eventopt, $enable_mpm_eventopt, eventopt.lo fdqueue.lo equeue.lo pod.lo,[ +APACHE_MPM_MODULE(eventopt, $enable_mpm_eventopt, eventopt.lo fdqueue.lo equeue.lo,[ AC_CHECK_FUNCS(pthread_kill) ], , [\$(MOD_MPM_EVENTOPT_LDADD)]) diff --git a/server/mpm/eventopt/eventopt.c b/server/mpm/eventopt/eventopt.c index 24d04856e1..2cc395c5be 100644 --- a/server/mpm/eventopt/eventopt.c +++ b/server/mpm/eventopt/eventopt.c @@ -347,7 +347,7 @@ static event_retained_data *retained; #define ID_FROM_CHILD_THREAD(c, t) ((c * thread_limit) + t) -static ap_eventopt_pod_t *pod; +static ap_pod_t *pod; /* The eventopt MPM respects a couple of runtime flags that can aid * in debugging. Setting the -DNO_DETACH flag will prevent the root process @@ -2245,25 +2245,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_eventopt_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; } } @@ -2485,7 +2485,7 @@ static void perform_idle_server_maintenance(void) if (idle_thread_count > max_spare_threads) { /* Kill off one child */ - ap_eventopt_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) { @@ -2711,7 +2711,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_eventopt_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); @@ -2732,7 +2732,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_eventopt_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) { @@ -2772,7 +2772,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_eventopt_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; @@ -2798,7 +2798,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_eventopt_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 @@ -2811,7 +2811,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_eventopt_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); @@ -2848,7 +2848,7 @@ static int event_open_logs(apr_pool_t * p, apr_pool_t * plog, } if (!one_process) { - if ((rv = ap_eventopt_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"); diff --git a/server/mpm/eventopt/pod.c b/server/mpm/eventopt/pod.c deleted file mode 100644 index bf6788b09e..0000000000 --- a/server/mpm/eventopt/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_eventopt); - -AP_DECLARE(apr_status_t) ap_eventopt_pod_open(apr_pool_t * p, ap_eventopt_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_eventopt_pod_check(ap_eventopt_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_eventopt_pod_close(ap_eventopt_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_eventopt_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_eventopt_pod_signal(ap_eventopt_pod_t * pod, int graceful) -{ - return pod_signal_internal(pod, graceful); -} - -AP_DECLARE(void) ap_eventopt_pod_killpg(ap_eventopt_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/eventopt/pod.h b/server/mpm/eventopt/pod.h deleted file mode 100644 index b3e254d402..0000000000 --- a/server/mpm/eventopt/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_EVENTOPT - * @{ - */ - -#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_eventopt_pod_t ap_eventopt_pod_t; - -struct ap_eventopt_pod_t -{ - apr_file_t *pod_in; - apr_file_t *pod_out; - apr_pool_t *p; -}; - -AP_DECLARE(apr_status_t) ap_eventopt_pod_open(apr_pool_t * p, ap_eventopt_pod_t ** pod); -AP_DECLARE(int) ap_eventopt_pod_check(ap_eventopt_pod_t * pod); -AP_DECLARE(apr_status_t) ap_eventopt_pod_close(ap_eventopt_pod_t * pod); -AP_DECLARE(apr_status_t) ap_eventopt_pod_signal(ap_eventopt_pod_t * pod, int graceful); -AP_DECLARE(void) ap_eventopt_pod_killpg(ap_eventopt_pod_t * pod, int num, int graceful); -/** @} */ diff --git a/server/mpm/worker/config3.m4 b/server/mpm/worker/config3.m4 index 7d7ab3dd66..68d861f494 100644 --- a/server/mpm/worker/config3.m4 +++ b/server/mpm/worker/config3.m4 @@ -1,7 +1,7 @@ APACHE_MPMPATH_INIT(worker) 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 86f7b39d26..0000000000 --- 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 ccb9cf9d70..0000000000 --- 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 548fcaec60..e5b0d5ce60 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -189,7 +189,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 @@ -1330,15 +1330,15 @@ 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; } } @@ -1347,7 +1347,7 @@ static void child_main(int child_num_arg) * 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; } } @@ -1572,7 +1572,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) { @@ -1827,7 +1827,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); @@ -1848,7 +1848,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) { @@ -1888,7 +1888,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; @@ -1913,7 +1913,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 @@ -1926,7 +1926,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); @@ -1962,7 +1962,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"); diff --git a/server/mpm_unix.c b/server/mpm_unix.c index 65c0940753..a70c2714ae 100644 --- a/server/mpm_unix.c +++ b/server/mpm_unix.c @@ -501,6 +501,107 @@ static apr_status_t pod_signal_internal(ap_pod_t *pod) return rv; } +AP_DECLARE(apr_status_t) ap_mpm_podx_open(apr_pool_t *p, ap_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_mpm_podx_check(ap_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 AP_MPM_PODX_RESTART_CHAR: + return AP_MPM_PODX_RESTART; + case AP_MPM_PODX_GRACEFUL_CHAR: + return AP_MPM_PODX_GRACEFUL; + } + } + return AP_MPM_PODX_NORESTART; +} + +AP_DECLARE(apr_status_t) ap_mpm_podx_close(ap_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 podx_signal_internal(ap_pod_t *pod, + ap_podx_restart_t graceful) +{ + apr_status_t rv; + apr_size_t one = 1; + char char_of_death = ' '; + switch (graceful) { + case AP_MPM_PODX_RESTART: + char_of_death = AP_MPM_PODX_RESTART_CHAR; + break; + case AP_MPM_PODX_GRACEFUL: + char_of_death = AP_MPM_PODX_GRACEFUL_CHAR; + break; + case AP_MPM_PODX_NORESTART: + break; + } + + 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(2404) + "write pipe_of_death"); + } + return rv; +} + +AP_DECLARE(apr_status_t) ap_mpm_podx_signal(ap_pod_t * pod, + ap_podx_restart_t graceful) +{ + return podx_signal_internal(pod, graceful); +} + +AP_DECLARE(void) ap_mpm_podx_killpg(ap_pod_t * pod, int num, + ap_podx_restart_t graceful) +{ + int i; + apr_status_t rv = APR_SUCCESS; + + for (i = 0; i < num && rv == APR_SUCCESS; i++) { + rv = podx_signal_internal(pod, graceful); + } +} + /* This function connects to the server and sends enough data to * ensure the child wakes up and processes a new connection. This * permits the MPM to skip the poll when there is only one listening |