summaryrefslogtreecommitdiffstats
path: root/server/mpm
diff options
context:
space:
mode:
authorJeff Trawick <trawick@apache.org>2011-04-25 23:21:22 +0200
committerJeff Trawick <trawick@apache.org>2011-04-25 23:21:22 +0200
commit462c69e0b533aa86d9a64fbbf8a0f2059520b126 (patch)
tree3da1ce7ff3322d2d8e08292764d1b07313e0d3b0 /server/mpm
parentmod_ldap: Make LDAPSharedCacheSize 0 create a non-shared-memory cache per (diff)
downloadapache2-462c69e0b533aa86d9a64fbbf8a0f2059520b126.tar.xz
apache2-462c69e0b533aa86d9a64fbbf8a0f2059520b126.zip
Add child_status hook for tracking creation/termination of MPM child
processes. Add end_generation hook for notification when the last MPM child of a generation exits. end_generation is implemented completely by core using the child_status hook run by the MPM. simple and mpmt_os2 MPMs don't currently run the child_status hook, so neither hook is invoked with those MPMs. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1096609 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server/mpm')
-rw-r--r--server/mpm/event/event.c70
-rw-r--r--server/mpm/netware/mpm_netware.c10
-rw-r--r--server/mpm/prefork/prefork.c34
-rw-r--r--server/mpm/winnt/mpm_winnt.c21
-rw-r--r--server/mpm/worker/worker.c69
5 files changed, 164 insertions, 40 deletions
diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c
index 6efd2f73e2..4efcc903a6 100644
--- a/server/mpm/event/event.c
+++ b/server/mpm/event/event.c
@@ -424,9 +424,47 @@ static int event_query(int query_code, int *result, apr_status_t *rv)
return OK;
}
-static void event_note_child_killed(int childnum)
+static void event_note_child_killed(int childnum, pid_t pid, ap_generation_t gen)
{
- ap_scoreboard_image->parent[childnum].pid = 0;
+ if (childnum != -1) { /* child had a scoreboard slot? */
+ ap_run_child_status(ap_server_conf,
+ ap_scoreboard_image->parent[childnum].pid,
+ ap_scoreboard_image->parent[childnum].generation,
+ childnum, MPM_CHILD_EXITED);
+ ap_scoreboard_image->parent[childnum].pid = 0;
+ }
+ else {
+ ap_run_child_status(ap_server_conf, pid, gen, -1, MPM_CHILD_EXITED);
+ }
+}
+
+static void event_note_child_started(int slot, pid_t pid)
+{
+ ap_scoreboard_image->parent[slot].pid = pid;
+ ap_run_child_status(ap_server_conf,
+ ap_scoreboard_image->parent[slot].pid,
+ retained->my_generation, slot, MPM_CHILD_STARTED);
+}
+
+static void event_note_child_lost_slot(int slot, pid_t newpid)
+{
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
+ "pid %" APR_PID_T_FMT " taking over scoreboard slot from "
+ "%" APR_PID_T_FMT "%s",
+ newpid,
+ ap_scoreboard_image->parent[slot].pid,
+ ap_scoreboard_image->parent[slot].quiescing ?
+ " (quiescing)" : "");
+ ap_run_child_status(ap_server_conf,
+ ap_scoreboard_image->parent[slot].pid,
+ ap_scoreboard_image->parent[slot].generation,
+ slot, MPM_CHILD_LOST_SLOT);
+ /* Don't forget about this exiting child process, or we
+ * won't be able to kill it if it doesn't exit by the
+ * time the server is shut down.
+ */
+ ap_register_extra_mpm_process(ap_scoreboard_image->parent[slot].pid,
+ ap_scoreboard_image->parent[slot].generation);
}
static const char *event_get_name(void)
@@ -442,6 +480,11 @@ static void clean_child_exit(int code)
if (pchild) {
apr_pool_destroy(pchild);
}
+
+ if (one_process) {
+ event_note_child_killed(/* slot */ 0, 0, 0);
+ }
+
exit(code);
}
@@ -1847,7 +1890,7 @@ static int make_child(server_rec * s, int slot)
if (one_process) {
set_signals();
- ap_scoreboard_image->parent[slot].pid = getpid();
+ event_note_child_started(slot, getpid());
child_main(slot);
/* NOTREACHED */
}
@@ -1894,19 +1937,11 @@ static int make_child(server_rec * s, int slot)
/* This new child process is squatting on the scoreboard
* entry owned by an exiting child process, which cannot
* exit until all active requests complete.
- * Don't forget about this exiting child process, or we
- * won't be able to kill it if it doesn't exit by the
- * time the server is shut down.
*/
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
- "taking over scoreboard slot from %" APR_PID_T_FMT "%s",
- ap_scoreboard_image->parent[slot].pid,
- ap_scoreboard_image->parent[slot].quiescing ?
- " (quiescing)" : "");
- ap_register_extra_mpm_process(ap_scoreboard_image->parent[slot].pid);
+ event_note_child_lost_slot(slot, pid);
}
ap_scoreboard_image->parent[slot].quiescing = 0;
- ap_scoreboard_image->parent[slot].pid = pid;
+ event_note_child_started(slot, pid);
return 0;
}
@@ -2104,6 +2139,7 @@ static void perform_idle_server_maintenance(void)
static void server_main_loop(int remaining_children_to_start)
{
+ ap_generation_t old_gen;
int child_slot;
apr_exit_why_e exitwhy;
int status, processed_status;
@@ -2134,7 +2170,7 @@ static void server_main_loop(int remaining_children_to_start)
SERVER_DEAD,
(request_rec *) NULL);
- ap_scoreboard_image->parent[child_slot].pid = 0;
+ event_note_child_killed(child_slot, 0, 0);
ap_scoreboard_image->parent[child_slot].quiescing = 0;
if (processed_status == APEXIT_CHILDSICK) {
/* resource shortage, minimize the fork rate */
@@ -2149,8 +2185,10 @@ static void server_main_loop(int remaining_children_to_start)
--remaining_children_to_start;
}
}
- else if (ap_unregister_extra_mpm_process(pid.pid) == 1) {
- /* handled */
+ else if (ap_unregister_extra_mpm_process(pid.pid, &old_gen) == 1) {
+
+ event_note_child_killed(-1, /* already out of the scoreboard */
+ pid.pid, old_gen);
#if APR_HAS_OTHER_CHILD
}
else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH,
diff --git a/server/mpm/netware/mpm_netware.c b/server/mpm/netware/mpm_netware.c
index 00b2b5ef67..f30fcbf354 100644
--- a/server/mpm/netware/mpm_netware.c
+++ b/server/mpm/netware/mpm_netware.c
@@ -880,6 +880,11 @@ static int netware_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
/* Only set slot 0 since that is all NetWare will ever have. */
ap_scoreboard_image->parent[0].pid = getpid();
+ ap_run_child_status(ap_server_conf,
+ ap_scoreboard_image->parent[0].pid,
+ ap_my_generation,
+ 0,
+ MPM_CHILD_STARTED);
set_signals();
@@ -917,6 +922,11 @@ static int netware_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
}
mpm_state = AP_MPMQ_STOPPING;
+ ap_run_child_status(ap_server_conf,
+ ap_scoreboard_image->parent[0].pid,
+ ap_my_generation,
+ 0,
+ MPM_CHILD_EXITED);
/* Shutdown the listen sockets so that we don't get stuck in a blocking call.
shutdown_listeners();*/
diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c
index 86c8d8c15d..eecd17739c 100644
--- a/server/mpm/prefork/prefork.c
+++ b/server/mpm/prefork/prefork.c
@@ -189,6 +189,25 @@ static void chdir_for_gprof(void)
#define chdir_for_gprof()
#endif
+static void prefork_note_child_killed(int childnum, pid_t pid,
+ ap_generation_t gen)
+{
+ AP_DEBUG_ASSERT(childnum != -1); /* no scoreboard squatting with this MPM */
+ ap_run_child_status(ap_server_conf,
+ ap_scoreboard_image->parent[childnum].pid,
+ ap_scoreboard_image->parent[childnum].generation,
+ childnum, MPM_CHILD_EXITED);
+ ap_scoreboard_image->parent[childnum].pid = 0;
+}
+
+static void prefork_note_child_started(int slot, pid_t pid)
+{
+ ap_scoreboard_image->parent[slot].pid = pid;
+ ap_run_child_status(ap_server_conf,
+ ap_scoreboard_image->parent[slot].pid,
+ retained->my_generation, slot, MPM_CHILD_STARTED);
+}
+
/* a clean exit from a child with proper cleanup */
static void clean_child_exit(int code) __attribute__ ((noreturn));
static void clean_child_exit(int code)
@@ -198,6 +217,11 @@ static void clean_child_exit(int code)
if (pchild) {
apr_pool_destroy(pchild);
}
+
+ if (one_process) {
+ prefork_note_child_killed(/* slot */ 0, 0, 0);
+ }
+
ap_mpm_pod_close(pod);
chdir_for_gprof();
exit(code);
@@ -306,11 +330,6 @@ static int prefork_query(int query_code, int *result, apr_status_t *rv)
return OK;
}
-static void prefork_note_child_killed(int childnum)
-{
- ap_scoreboard_image->parent[childnum].pid = 0;
-}
-
static const char *prefork_get_name(void)
{
return "prefork";
@@ -716,7 +735,7 @@ static int make_child(server_rec *s, int slot)
apr_signal(SIGQUIT, SIG_DFL);
#endif
apr_signal(SIGTERM, sig_term);
- ap_scoreboard_image->parent[slot].pid = getpid();
+ prefork_note_child_started(slot, getpid());
child_main(slot);
/* NOTREACHED */
}
@@ -774,7 +793,7 @@ static int make_child(server_rec *s, int slot)
child_main(slot);
}
- ap_scoreboard_image->parent[slot].pid = pid;
+ prefork_note_child_started(slot, pid);
return 0;
}
@@ -995,6 +1014,7 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
if (child_slot >= 0) {
(void) ap_update_child_status_from_indexes(child_slot, 0, SERVER_DEAD,
(request_rec *) NULL);
+ prefork_note_child_killed(child_slot, 0, 0);
if (processed_status == APEXIT_CHILDSICK) {
/* child detected a resource shortage (E[NM]FILE, ENOBUFS, etc)
* cut the fork rate to the minimum
diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c
index 0d68ea3bc4..e819d863d7 100644
--- a/server/mpm/winnt/mpm_winnt.c
+++ b/server/mpm/winnt/mpm_winnt.c
@@ -139,6 +139,22 @@ AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF,
{ NULL }
};
+static void winnt_note_child_started(int slot, pid_t pid)
+{
+ ap_scoreboard_image->parent[slot].pid = pid;
+ ap_run_child_status(ap_server_conf,
+ ap_scoreboard_image->parent[slot].pid,
+ my_generation, slot, MPM_CHILD_STARTED);
+}
+
+static void winnt_note_child_killed(int slot)
+{
+ ap_run_child_status(ap_server_conf,
+ ap_scoreboard_image->parent[slot].pid,
+ ap_scoreboard_image->parent[slot].generation,
+ slot, MPM_CHILD_EXITED);
+ ap_scoreboard_image->parent[slot].pid = 0;
+}
/*
* Signalling Apache on NT.
@@ -767,7 +783,7 @@ static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_even
* child at once.
*/
ap_scoreboard_image->parent[0].quiescing = 0;
- ap_scoreboard_image->parent[0].pid = child_pid;
+ winnt_note_child_started(/* slot */ 0, child_pid);
/* Wait for shutdown or restart events or for child death */
winnt_mpm_state = AP_MPMQ_RUNNING;
@@ -843,6 +859,9 @@ static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_even
CloseHandle(event_handles[CHILD_HANDLE]);
event_handles[CHILD_HANDLE] = NULL;
}
+
+ winnt_note_child_killed(/* slot */ 0);
+
if (restart_pending) {
++my_generation;
ap_scoreboard_image->global->running_generation = my_generation;
diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c
index 705451bd22..752679d458 100644
--- a/server/mpm/worker/worker.c
+++ b/server/mpm/worker/worker.c
@@ -372,9 +372,47 @@ static int worker_query(int query_code, int *result, apr_status_t *rv)
return OK;
}
-static void worker_note_child_killed(int childnum)
+static void worker_note_child_killed(int childnum, pid_t pid, ap_generation_t gen)
{
- ap_scoreboard_image->parent[childnum].pid = 0;
+ if (childnum != -1) { /* child had a scoreboard slot? */
+ ap_run_child_status(ap_server_conf,
+ ap_scoreboard_image->parent[childnum].pid,
+ ap_scoreboard_image->parent[childnum].generation,
+ childnum, MPM_CHILD_EXITED);
+ ap_scoreboard_image->parent[childnum].pid = 0;
+ }
+ else {
+ ap_run_child_status(ap_server_conf, pid, gen, -1, MPM_CHILD_EXITED);
+ }
+}
+
+static void worker_note_child_started(int slot, pid_t pid)
+{
+ ap_scoreboard_image->parent[slot].pid = pid;
+ ap_run_child_status(ap_server_conf,
+ ap_scoreboard_image->parent[slot].pid,
+ retained->my_generation, slot, MPM_CHILD_STARTED);
+}
+
+static void worker_note_child_lost_slot(int slot, pid_t newpid)
+{
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
+ "pid %" APR_PID_T_FMT " taking over scoreboard slot from "
+ "%" APR_PID_T_FMT "%s",
+ newpid,
+ ap_scoreboard_image->parent[slot].pid,
+ ap_scoreboard_image->parent[slot].quiescing ?
+ " (quiescing)" : "");
+ ap_run_child_status(ap_server_conf,
+ ap_scoreboard_image->parent[slot].pid,
+ ap_scoreboard_image->parent[slot].generation,
+ slot, MPM_CHILD_LOST_SLOT);
+ /* Don't forget about this exiting child process, or we
+ * won't be able to kill it if it doesn't exit by the
+ * time the server is shut down.
+ */
+ ap_register_extra_mpm_process(ap_scoreboard_image->parent[slot].pid,
+ ap_scoreboard_image->parent[slot].generation);
}
static const char *worker_get_name(void)
@@ -390,6 +428,11 @@ static void clean_child_exit(int code)
if (pchild) {
apr_pool_destroy(pchild);
}
+
+ if (one_process) {
+ worker_note_child_killed(/* slot */ 0, 0, 0);
+ }
+
exit(code);
}
@@ -1344,7 +1387,7 @@ static int make_child(server_rec *s, int slot)
if (one_process) {
set_signals();
- ap_scoreboard_image->parent[slot].pid = getpid();
+ worker_note_child_started(slot, getpid());
child_main(slot);
/* NOTREACHED */
}
@@ -1390,19 +1433,11 @@ static int make_child(server_rec *s, int slot)
/* This new child process is squatting on the scoreboard
* entry owned by an exiting child process, which cannot
* exit until all active requests complete.
- * Don't forget about this exiting child process, or we
- * won't be able to kill it if it doesn't exit by the
- * time the server is shut down.
*/
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
- "taking over scoreboard slot from %" APR_PID_T_FMT "%s",
- ap_scoreboard_image->parent[slot].pid,
- ap_scoreboard_image->parent[slot].quiescing ?
- " (quiescing)" : "");
- ap_register_extra_mpm_process(ap_scoreboard_image->parent[slot].pid);
+ worker_note_child_lost_slot(slot, pid);
}
ap_scoreboard_image->parent[slot].quiescing = 0;
- ap_scoreboard_image->parent[slot].pid = pid;
+ worker_note_child_started(slot, pid);
return 0;
}
@@ -1611,6 +1646,7 @@ static void perform_idle_server_maintenance(void)
static void server_main_loop(int remaining_children_to_start)
{
+ ap_generation_t old_gen;
int child_slot;
apr_exit_why_e exitwhy;
int status, processed_status;
@@ -1640,7 +1676,7 @@ static void server_main_loop(int remaining_children_to_start)
ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD,
(request_rec *) NULL);
- ap_scoreboard_image->parent[child_slot].pid = 0;
+ worker_note_child_killed(child_slot, 0, 0);
ap_scoreboard_image->parent[child_slot].quiescing = 0;
if (processed_status == APEXIT_CHILDSICK) {
/* resource shortage, minimize the fork rate */
@@ -1655,8 +1691,9 @@ static void server_main_loop(int remaining_children_to_start)
--remaining_children_to_start;
}
}
- else if (ap_unregister_extra_mpm_process(pid.pid) == 1) {
- /* handled */
+ else if (ap_unregister_extra_mpm_process(pid.pid, &old_gen) == 1) {
+ worker_note_child_killed(-1, /* already out of the scoreboard */
+ pid.pid, old_gen);
#if APR_HAS_OTHER_CHILD
}
else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH,