summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Jagielski <jim@apache.org>2007-06-13 16:23:19 +0000
committerJim Jagielski <jim@apache.org>2007-06-13 16:23:19 +0000
commit91f25252ce2b5311fa76f7c6cd299f745656e0b6 (patch)
tree459cad01fd95d9dfe7a260c0e3dbf9df2e5139c6
parentebf474ed028be5f363f872d23960e4abb1a27225 (diff)
downloadhttpd-2.2-pid-table.tar.gz
Backport of PID table code from trunk to 2.2...httpd-2.2-pid-table
Create a branch for this until we test enough to fold into 2.2 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/httpd-2.2-pid-table@546948 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--include/mpm_common.h8
-rw-r--r--server/main.c1
-rw-r--r--server/mpm/beos/mpm.h5
-rw-r--r--server/mpm/experimental/event/event.c5
-rw-r--r--server/mpm/experimental/event/mpm.h5
-rw-r--r--server/mpm/mpmt_os2/mpm.h1
-rw-r--r--server/mpm/mpmt_os2/mpmt_os2.c11
-rw-r--r--server/mpm/netware/mpm.h5
-rw-r--r--server/mpm/prefork/mpm.h5
-rw-r--r--server/mpm/prefork/prefork.c34
-rw-r--r--server/mpm/worker/mpm.h5
-rw-r--r--server/mpm/worker/worker.c7
-rw-r--r--server/mpm_common.c39
-rw-r--r--server/scoreboard.c4
14 files changed, 115 insertions, 20 deletions
diff --git a/include/mpm_common.h b/include/mpm_common.h
index bc4480a792..27b317882f 100644
--- a/include/mpm_common.h
+++ b/include/mpm_common.h
@@ -350,6 +350,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 29557f2374..57e9ba1679 100644
--- a/server/main.c
+++ b/server/main.c
@@ -460,6 +460,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 d61594b060..cadf36521a 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 e105c25e97..c7c5bbbf97 100644
--- a/server/mpm/experimental/event/event.c
+++ b/server/mpm/experimental/event/event.c
@@ -1582,6 +1582,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;
}
@@ -1999,10 +2000,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/experimental/event/mpm.h b/server/mpm/experimental/event/mpm.h
index cf4e61d911..c2731afd8c 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/mpmt_os2/mpm.h b/server/mpm/mpmt_os2/mpm.h
index f8bbc30eb3..e324d79a38 100644
--- a/server/mpm/mpmt_os2/mpm.h
+++ b/server/mpm/mpmt_os2/mpm.h
@@ -30,6 +30,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 b3a83c43b2..cb6ecc167f 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 106d62a509..93f1824e5a 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 bf1fb94999..51743d2cca 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 ba50581b6a..8c2a13710e 100644
--- a/server/mpm/prefork/prefork.c
+++ b/server/mpm/prefork/prefork.c
@@ -306,13 +306,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;
}
@@ -1127,8 +1133,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++;
+ }
}
}
@@ -1166,10 +1174,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;
+ }
}
}
}
@@ -1222,7 +1232,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 335f4b6ace..a8585d375e 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 a9d822f541..eba49ef974 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;
}
@@ -1590,6 +1592,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 */
@@ -1814,10 +1817,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 c654cbfb22..a99f6b17ca 100644
--- a/server/mpm_common.c
+++ b/server/mpm_common.c
@@ -86,6 +86,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));
@@ -113,6 +148,7 @@ int ap_unregister_extra_mpm_process(pid_t pid)
extras = cur->next;
}
free(cur);
+ ap_unset_pid_table(pid);
return 1; /* found */
}
else {
@@ -127,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 9cb7359a54..bc3d5cd2f4 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;
@@ -364,7 +365,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;
}
}