diff options
-rw-r--r-- | include/mpm_common.h | 8 | ||||
-rw-r--r-- | server/main.c | 1 | ||||
-rw-r--r-- | server/mpm/beos/mpm.h | 5 | ||||
-rw-r--r-- | server/mpm/mpmt_os2/mpm.h | 1 | ||||
-rw-r--r-- | server/mpm/mpmt_os2/mpmt_os2.c | 11 | ||||
-rw-r--r-- | server/mpm/netware/mpm.h | 5 | ||||
-rw-r--r-- | server/mpm/prefork/mpm.h | 5 | ||||
-rw-r--r-- | server/mpm/prefork/prefork.c | 22 | ||||
-rw-r--r-- | server/mpm/worker/mpm.h | 5 | ||||
-rw-r--r-- | server/mpm/worker/worker.c | 3 | ||||
-rw-r--r-- | server/mpm_common.c | 39 | ||||
-rw-r--r-- | server/scoreboard.c | 4 |
12 files changed, 95 insertions, 14 deletions
diff --git a/include/mpm_common.h b/include/mpm_common.h index 68ead5f7d7..34d65fc05f 100644 --- a/include/mpm_common.h +++ b/include/mpm_common.h @@ -261,6 +261,14 @@ const char *ap_mpm_set_scoreboard(cmd_parms *cmd, void *dummy, #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); + +/* * The directory that the server changes directory to dump core. */ #ifdef AP_MPM_WANT_SET_COREDUMPDIR diff --git a/server/main.c b/server/main.c index 7007ce8c04..8a0e9ab2a8 100644 --- a/server/main.c +++ b/server/main.c @@ -404,6 +404,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); ap_setup_prelinked_modules(process); diff --git a/server/mpm/beos/mpm.h b/server/mpm/beos/mpm.h index 57221b1c65..d139f15780 100644 --- a/server/mpm/beos/mpm.h +++ b/server/mpm/beos/mpm.h @@ -22,7 +22,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/mpmt_os2/mpm.h b/server/mpm/mpmt_os2/mpm.h index 15f341ddfd..507bfd91d1 100644 --- a/server/mpm/mpmt_os2/mpm.h +++ b/server/mpm/mpmt_os2/mpm.h @@ -22,6 +22,7 @@ #include "httpd.h" #include "mpm_default.h" #include "scoreboard.h" +#include "mpm_common.h" #define MPM_NAME "MPMT_OS2" diff --git a/server/mpm/mpmt_os2/mpmt_os2.c b/server/mpm/mpmt_os2/mpmt_os2.c index 2c7f57bf23..b98699c9f6 100644 --- a/server/mpm/mpmt_os2/mpmt_os2.c +++ b/server/mpm/mpmt_os2/mpmt_os2.c @@ -281,6 +281,7 @@ static char master_main() #endif if (one_process) { ap_scoreboard_image->parent[0].pid = getpid(); + ap_set_pid_table(getpid()); ap_mpm_child_main(pconf); return FALSE; } @@ -307,6 +308,7 @@ static char master_main() rc = DosWaitChild(DCWA_PROCESSTREE, DCWW_NOWAIT, &proc_rc, &child_pid, 0); if (rc == 0) { + ap_unset_pid_table(child_pid); /* A child has terminated, remove its scoreboard entry & terminate if necessary */ for (slot=0; ap_scoreboard_image->parent[slot].pid != child_pid && slot < HARD_SERVER_LIMIT; slot++); @@ -330,7 +332,13 @@ static char master_main() /* Signal children to shut down, either gracefully or immediately */ for (slot=0; slot<HARD_SERVER_LIMIT; slot++) { - kill(ap_scoreboard_image->parent[slot].pid, is_graceful ? SIGHUP : SIGTERM); + PID pid; + + pid = ap_scoreboard_image->parent[n].pid; + if (ap_in_pid_table(pid)) { + kill(pid, is_graceful ? SIGHUP : SIGTERM); + ap_unset_pid_table(pid); + } } DosFreeMem(parent_info); @@ -364,6 +372,7 @@ static void spawn_child(int slot) } ap_scoreboard_image->parent[slot].pid = proc_rc.codeTerminate; + ap_set_pid_table(proc_rc.codeTerminate); } diff --git a/server/mpm/netware/mpm.h b/server/mpm/netware/mpm.h index 4b9a839204..0eeea2091c 100644 --- a/server/mpm/netware/mpm.h +++ b/server/mpm/netware/mpm.h @@ -38,7 +38,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_thread_stack_size; diff --git a/server/mpm/prefork/mpm.h b/server/mpm/prefork/mpm.h index 51f810b39f..c89386e9b1 100644 --- a/server/mpm/prefork/mpm.h +++ b/server/mpm/prefork/mpm.h @@ -42,7 +42,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 8667b4ab51..5f4aa6b603 100644 --- a/server/mpm/prefork/prefork.c +++ b/server/mpm/prefork/prefork.c @@ -303,14 +303,19 @@ 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; } @@ -705,6 +710,7 @@ static int make_child(server_rec *s, int slot) } ap_scoreboard_image->parent[slot].pid = pid; + ap_set_pid_table(pid); return 0; } diff --git a/server/mpm/worker/mpm.h b/server/mpm/worker/mpm.h index 31830c6cdb..eb095798ea 100644 --- a/server/mpm/worker/mpm.h +++ b/server/mpm/worker/mpm.h @@ -39,7 +39,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 6e0da64720..cc78669436 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -1297,6 +1297,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; } @@ -1527,6 +1529,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.pid); ap_scoreboard_image->parent[child_slot].quiescing = 0; if (processed_status == APEXIT_CHILDSICK) { /* resource shortage, minimize the fork rate */ diff --git a/server/mpm_common.c b/server/mpm_common.c index b21dc8ad27..5f0ee279a6 100644 --- a/server/mpm_common.c +++ b/server/mpm_common.c @@ -70,6 +70,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; + apr_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]; + apr_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]; + apr_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)); @@ -97,6 +132,7 @@ int ap_unregister_extra_mpm_process(pid_t pid) extras = cur->next; } free(cur); + ap_unset_pid_table(pid); return 1; /* found */ } else { @@ -111,6 +147,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 c0b0ed0575..a867ba1139 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; @@ -339,7 +340,8 @@ AP_DECLARE(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; } } |