diff options
author | Jeff Trawick <trawick@apache.org> | 2011-04-25 23:21:22 +0200 |
---|---|---|
committer | Jeff Trawick <trawick@apache.org> | 2011-04-25 23:21:22 +0200 |
commit | 462c69e0b533aa86d9a64fbbf8a0f2059520b126 (patch) | |
tree | 3da1ce7ff3322d2d8e08292764d1b07313e0d3b0 /server/mpm | |
parent | mod_ldap: Make LDAPSharedCacheSize 0 create a non-shared-memory cache per (diff) | |
download | apache2-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.c | 70 | ||||
-rw-r--r-- | server/mpm/netware/mpm_netware.c | 10 | ||||
-rw-r--r-- | server/mpm/prefork/prefork.c | 34 | ||||
-rw-r--r-- | server/mpm/winnt/mpm_winnt.c | 21 | ||||
-rw-r--r-- | server/mpm/worker/worker.c | 69 |
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, |