From: Jim Jagielski Date: Fri, 1 Jun 2007 19:28:31 +0000 (+0000) Subject: Create work-in-progress branch X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a2d88accbc7417983a9fc3a92e358fae9c9ee5ff;p=thirdparty%2Fapache%2Fhttpd.git Create work-in-progress branch git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/httpd-pid-table@543583 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/mpm_common.h b/include/mpm_common.h index 20a74ac6424..1b69fb5e4cd 100644 --- a/include/mpm_common.h +++ b/include/mpm_common.h @@ -349,6 +349,14 @@ extern const char *ap_mpm_set_exception_hook(cmd_parms *cmd, void *dummy, const char *arg); #endif +/* + * The parent process pid table + */ +extern apr_table_t *ap_pid_table; +int ap_in_pid_table(pid_t pid); +void ap_set_pid_table(pid_t pid); +void ap_unset_pid_table(pid_t pid); + AP_DECLARE_HOOK(int,monitor,(apr_pool_t *p)) #ifdef __cplusplus diff --git a/server/main.c b/server/main.c index 7285eae1a0e..f8a90a75f6e 100644 --- a/server/main.c +++ b/server/main.c @@ -480,6 +480,7 @@ int main(int argc, const char * const argv[]) ap_server_pre_read_config = apr_array_make(pcommands, 1, sizeof(char *)); ap_server_post_read_config = apr_array_make(pcommands, 1, sizeof(char *)); ap_server_config_defines = apr_array_make(pcommands, 1, sizeof(char *)); + ap_pid_table = apr_table_make(pglobal, 1024); error = ap_setup_prelinked_modules(process); if (error) { diff --git a/server/mpm/beos/mpm.h b/server/mpm/beos/mpm.h index d61594b0603..cadf36521a0 100644 --- a/server/mpm/beos/mpm.h +++ b/server/mpm/beos/mpm.h @@ -31,7 +31,10 @@ #define MPM_NAME "Beos" #define MPM_CHILD_PID(i) (ap_scoreboard_image->servers[0][i].tid) -#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) +#define MPM_NOTE_CHILD_KILLED(i) do { \ + ap_unset_pid_table(MPM_CHILD_PID(i)); \ + MPM_CHILD_PID(i) = 0; \ + } while(0) #define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES #define AP_MPM_WANT_WAIT_OR_TIMEOUT diff --git a/server/mpm/experimental/event/event.c b/server/mpm/experimental/event/event.c index 417f360cc13..7729af61803 100644 --- a/server/mpm/experimental/event/event.c +++ b/server/mpm/experimental/event/event.c @@ -1643,6 +1643,7 @@ static int make_child(server_rec * s, int slot) /* else */ ap_scoreboard_image->parent[slot].quiescing = 0; ap_scoreboard_image->parent[slot].pid = pid; + ap_set_pid_table(pid); return 0; } @@ -2062,10 +2063,13 @@ int ap_mpm_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s) active_children = 0; for (index = 0; index < ap_daemons_limit; ++index) { if (MPM_CHILD_PID(index) != 0) { - if (kill(MPM_CHILD_PID(index), 0) == 0) { + if (ap_in_pid_table(MPM_CHILD_PID(index))) { + if (kill(MPM_CHILD_PID(index), 0) == 0) { active_children = 1; + ap_unset_pid_table(MPM_CHILD_PID(index)); /* Having just one child is enough to stay around */ break; + } } } } diff --git a/server/mpm/experimental/event/mpm.h b/server/mpm/experimental/event/mpm.h index cf4e61d9115..c2731afd8c9 100644 --- a/server/mpm/experimental/event/mpm.h +++ b/server/mpm/experimental/event/mpm.h @@ -50,7 +50,10 @@ #define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) -#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) +#define MPM_NOTE_CHILD_KILLED(i) do { \ + ap_unset_pid_table(MPM_CHILD_PID(i)); \ + MPM_CHILD_PID(i) = 0; \ + } while(0) #define MPM_ACCEPT_FUNC unixd_accept extern int ap_threads_per_child; diff --git a/server/mpm/experimental/leader/mpm.h b/server/mpm/experimental/leader/mpm.h index d30be86a1fd..680c9ca6912 100644 --- a/server/mpm/experimental/leader/mpm.h +++ b/server/mpm/experimental/leader/mpm.h @@ -50,7 +50,10 @@ #define AP_MPM_USES_POD 1 #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) -#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) +#define MPM_NOTE_CHILD_KILLED(i) do { \ + ap_unset_pid_table(MPM_CHILD_PID(i)); \ + MPM_CHILD_PID(i) = 0; \ + } while(0) #define MPM_ACCEPT_FUNC unixd_accept extern int ap_threads_per_child; diff --git a/server/mpm/experimental/perchild/mpm.h b/server/mpm/experimental/perchild/mpm.h index af972387287..c54863efe39 100644 --- a/server/mpm/experimental/perchild/mpm.h +++ b/server/mpm/experimental/perchild/mpm.h @@ -49,7 +49,10 @@ #define AP_MPM_USES_POD #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) -#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) +#define MPM_NOTE_CHILD_KILLED(i) do { \ + ap_unset_pid_table(MPM_CHILD_PID(i)); \ + MPM_CHILD_PID(i) = 0; \ + } while(0) #define MPM_ACCEPT_FUNC unixd_accept /* Table of child status */ diff --git a/server/mpm/experimental/threadpool/mpm.h b/server/mpm/experimental/threadpool/mpm.h index 806011b8857..624f37c89a5 100644 --- a/server/mpm/experimental/threadpool/mpm.h +++ b/server/mpm/experimental/threadpool/mpm.h @@ -49,7 +49,10 @@ #define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) -#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) +#define MPM_NOTE_CHILD_KILLED(i) do { \ + ap_unset_pid_table(MPM_CHILD_PID(i)); \ + MPM_CHILD_PID(i) = 0; \ + } while(0) #define MPM_ACCEPT_FUNC unixd_accept extern int ap_threads_per_child; diff --git a/server/mpm/netware/mpm.h b/server/mpm/netware/mpm.h index 106d62a5095..93f1824e5a5 100644 --- a/server/mpm/netware/mpm.h +++ b/server/mpm/netware/mpm.h @@ -48,7 +48,10 @@ */ #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) -#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) +#define MPM_NOTE_CHILD_KILLED(i) do { \ + ap_unset_pid_table(MPM_CHILD_PID(i)); \ + MPM_CHILD_PID(i) = 0; \ + } while(0) extern int ap_threads_per_child; extern int ap_max_workers_limit; diff --git a/server/mpm/prefork/mpm.h b/server/mpm/prefork/mpm.h index bf1fb949996..51743d2ccae 100644 --- a/server/mpm/prefork/mpm.h +++ b/server/mpm/prefork/mpm.h @@ -52,7 +52,10 @@ #define AP_MPM_USES_POD 1 #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) -#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) +#define MPM_NOTE_CHILD_KILLED(i) do { \ + ap_unset_pid_table(MPM_CHILD_PID(i)); \ + MPM_CHILD_PID(i) = 0; \ + } while(0) #define MPM_ACCEPT_FUNC unixd_accept extern int ap_threads_per_child; diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c index 31c19df84f8..6a51f657f7d 100644 --- a/server/mpm/prefork/prefork.c +++ b/server/mpm/prefork/prefork.c @@ -305,13 +305,18 @@ int reap_children(int *exitcode, apr_exit_why_e *status) int n, pid; for (n = 0; n < ap_max_daemons_limit; ++n) { - if (ap_scoreboard_image->servers[n][0].status != SERVER_DEAD && - kill((pid = ap_scoreboard_image->parent[n].pid), 0) == -1) { - ap_update_child_status_from_indexes(n, 0, SERVER_DEAD, NULL); - /* just mark it as having a successful exit status */ - *status = APR_PROC_EXIT; - *exitcode = 0; - return(pid); + pid = ap_scoreboard_image->parent[n].pid; + if (ap_scoreboard_image->servers[n][0].status != SERVER_DEAD) { + if (ap_in_pid_table(pid)) { + if (kill(pid, 0) == -1) { + ap_update_child_status_from_indexes(n, 0, SERVER_DEAD, NULL); + /* just mark it as having a successful exit status */ + *status = APR_PROC_EXIT; + *exitcode = 0; + ap_unset_pid_table(pid); + return(pid); + } + } } } return 0; @@ -737,6 +742,7 @@ static int make_child(server_rec *s, int slot) } ap_scoreboard_image->parent[slot].pid = pid; + ap_set_pid_table(pid); return 0; } @@ -1119,8 +1125,10 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) for (index = 0; index < ap_daemons_limit; ++index) { if (ap_scoreboard_image->servers[index][0].status != SERVER_DEAD) { /* Ask each child to close its listeners. */ - kill(MPM_CHILD_PID(index), AP_SIG_GRACEFUL); - active_children++; + if (ap_in_pid_table(MPM_CHILD_PID(index))) { + kill(MPM_CHILD_PID(index), AP_SIG_GRACEFUL); + active_children++; + } } } @@ -1158,10 +1166,12 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) active_children = 0; for (index = 0; index < ap_daemons_limit; ++index) { if (MPM_CHILD_PID(index) != 0) { - if (kill(MPM_CHILD_PID(index), 0) == 0) { + if (ap_in_pid_table(MPM_CHILD_PID(index))) { + if (kill(MPM_CHILD_PID(index), 0) == 0) { active_children = 1; /* Having just one child is enough to stay around */ break; + } } } } @@ -1214,7 +1224,9 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) * piped loggers, etc. They almost certainly won't handle * it gracefully. */ - kill(ap_scoreboard_image->parent[index].pid, AP_SIG_GRACEFUL); + if (ap_in_pid_table(MPM_CHILD_PID(index))) { + kill(MPM_CHILD_PID(index), AP_SIG_GRACEFUL); + } } } } diff --git a/server/mpm/worker/mpm.h b/server/mpm/worker/mpm.h index 335f4b6ace4..a8585d375ee 100644 --- a/server/mpm/worker/mpm.h +++ b/server/mpm/worker/mpm.h @@ -50,7 +50,10 @@ #define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) -#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) +#define MPM_NOTE_CHILD_KILLED(i) do { \ + ap_unset_pid_table(MPM_CHILD_PID(i)); \ + MPM_CHILD_PID(i) = 0; \ + } while(0) #define MPM_ACCEPT_FUNC unixd_accept extern int ap_threads_per_child; diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c index e8eca8c197a..0185002d489 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -1360,6 +1360,8 @@ static int make_child(server_rec *s, int slot) } ap_scoreboard_image->parent[slot].quiescing = 0; ap_scoreboard_image->parent[slot].pid = pid; + ap_set_pid_table(pid); + return 0; } @@ -1600,6 +1602,7 @@ static void server_main_loop(int remaining_children_to_start) (request_rec *) NULL); ap_scoreboard_image->parent[child_slot].pid = 0; + ap_unset_pid_table(pid); ap_scoreboard_image->parent[child_slot].quiescing = 0; if (processed_status == APEXIT_CHILDSICK) { /* resource shortage, minimize the fork rate */ @@ -1816,10 +1819,12 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) active_children = 0; for (index = 0; index < ap_daemons_limit; ++index) { if (MPM_CHILD_PID(index) != 0) { - if (kill(MPM_CHILD_PID(index), 0) == 0) { + if (ap_in_pid_table(MPM_CHILD_PID(index))) { + if (kill(MPM_CHILD_PID(index), 0) == 0) { active_children = 1; /* Having just one child is enough to stay around */ break; + } } } } diff --git a/server/mpm_common.c b/server/mpm_common.c index 832cc4084b4..f99e70c4d82 100644 --- a/server/mpm_common.c +++ b/server/mpm_common.c @@ -87,6 +87,41 @@ typedef struct extra_process_t { static extra_process_t *extras; +/* + * Parent process local storage of child pids + */ +apr_table_t *ap_pid_table; + +/* + * Check the pid table to see if the actual pid exists + */ +int ap_in_pid_table(pid_t pid) { + char apid[64]; + const char *spid; + snprintf(apid, sizeof(apid), "%" APR_PID_T_FMT, pid); + spid = apr_table_get(ap_pid_table, apid); + if (spid && spid[0] == '1' && spid[1] == '\0') + return 1; + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, + "child process %" APR_PID_T_FMT + " does not exist in local pid table", pid); + return 0; + } +} + +void ap_set_pid_table(pid_t pid) { + char apid[64]; + snprintf(apid, sizeof(apid), "%" APR_PID_T_FMT, pid); + apr_table_set(ap_pid_table, apid, "1"); +} + +void ap_unset_pid_table(pid_t pid) { + char apid[64]; + snprintf(apid, sizeof(apid), "%" APR_PID_T_FMT, pid); + apr_table_unset(ap_pid_table, apid); +} + void ap_register_extra_mpm_process(pid_t pid) { extra_process_t *p = (extra_process_t *)malloc(sizeof(extra_process_t)); @@ -128,6 +163,9 @@ static int reclaim_one_pid(pid_t pid, action_t action) apr_status_t waitret; proc.pid = pid; + if (!ap_in_pid_table(pid)) { + return 0; + } waitret = apr_proc_wait(&proc, NULL, NULL, APR_NOWAIT); if (waitret != APR_CHILD_NOTDONE) { return 1; diff --git a/server/scoreboard.c b/server/scoreboard.c index 99238bac236..2e00452c95c 100644 --- a/server/scoreboard.c +++ b/server/scoreboard.c @@ -35,6 +35,7 @@ #include "ap_mpm.h" #include "mpm.h" +#include "mpm_common.h" #include "scoreboard.h" AP_DECLARE_DATA scoreboard *ap_scoreboard_image = NULL; @@ -363,7 +364,8 @@ int find_child_by_pid(apr_proc_t *pid) ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_daemons_limit); for (i = 0; i < max_daemons_limit; ++i) { - if (ap_scoreboard_image->parent[i].pid == pid->pid) { + if (ap_scoreboard_image->parent[i].pid == pid->pid && + ap_in_pid_table(pid->pid)) { return i; } }