summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Bloom <rbb@apache.org>2000-05-24 02:42:01 +0200
committerRyan Bloom <rbb@apache.org>2000-05-24 02:42:01 +0200
commit93d9ac51ce04eeaa9e83caa7a50fff9067f27737 (patch)
treefe6c90023f0c6cf10930e786afb3f7c4396404f8
parentRename stdin, stdout, stderr from new ap_proc_t to in, out, and err because (diff)
downloadapache2-93d9ac51ce04eeaa9e83caa7a50fff9067f27737.tar.xz
apache2-93d9ac51ce04eeaa9e83caa7a50fff9067f27737.zip
Fix a memory leak with ap_wait_or_timeout.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@85286 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--include/mpm_common.h2
-rw-r--r--server/mpm/dexter/dexter.c14
-rw-r--r--server/mpm/mpmt_pthread/mpmt_pthread.c15
-rw-r--r--server/mpm/prefork/prefork.c14
-rw-r--r--server/mpm_common.c13
5 files changed, 30 insertions, 28 deletions
diff --git a/include/mpm_common.h b/include/mpm_common.h
index f693f6011c..0e83e8a597 100644
--- a/include/mpm_common.h
+++ b/include/mpm_common.h
@@ -75,7 +75,7 @@ extern "C" {
#endif
void ap_reclaim_child_processes(int terminate);
-ap_proc_t *ap_wait_or_timeout(ap_wait_t *status, ap_pool_t *p);
+void ap_wait_or_timeout(ap_wait_t *status, ap_proc_t *ret, ap_pool_t *p);
#ifdef __cplusplus
}
diff --git a/server/mpm/dexter/dexter.c b/server/mpm/dexter/dexter.c
index b2f505d974..0805cfddfa 100644
--- a/server/mpm/dexter/dexter.c
+++ b/server/mpm/dexter/dexter.c
@@ -974,19 +974,19 @@ static void server_main_loop(int remaining_children_to_start)
{
int child_slot;
ap_wait_t status;
- ap_proc_t *pid;
+ ap_proc_t pid;
int i;
while (!restart_pending && !shutdown_pending) {
- pid = ap_wait_or_timeout(&status, pconf);
+ ap_wait_or_timeout(&status, &pid, pconf);
- if (pid != NULL) {
- process_child_status(pid, status);
+ if (pid.pid != -1) {
+ process_child_status(&pid, status);
/* non-fatal death... note that it's gone in the child table and
* clean out the status table. */
child_slot = -1;
for (i = 0; i < ap_max_daemons_limit; ++i) {
- if (ap_child_table[i].pid == pid->pid) {
+ if (ap_child_table[i].pid == pid.pid) {
int j;
child_slot = i;
@@ -1009,7 +1009,7 @@ static void server_main_loop(int remaining_children_to_start)
}
#ifdef APR_HAS_OTHER_CHILD
}
- else if (ap_reap_other_child(pid, status) == 0) {
+ else if (ap_reap_other_child(&pid, status) == 0) {
/* handled */
#endif
}
@@ -1021,7 +1021,7 @@ static void server_main_loop(int remaining_children_to_start)
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, errno,
ap_server_conf,
"long lost child came home! (pid %ld)",
- (long)pid->pid);
+ (long)pid.pid);
}
/* Don't perform idle maintenance when a child dies,
* only do it when there's a timeout. Remember only a
diff --git a/server/mpm/mpmt_pthread/mpmt_pthread.c b/server/mpm/mpmt_pthread/mpmt_pthread.c
index d07a832530..2c4355fa09 100644
--- a/server/mpm/mpmt_pthread/mpmt_pthread.c
+++ b/server/mpm/mpmt_pthread/mpmt_pthread.c
@@ -1015,17 +1015,16 @@ static void server_main_loop(int remaining_children_to_start)
{
int child_slot;
ap_wait_t status;
- ap_proc_t *pid;
+ ap_proc_t pid;
int i;
while (!restart_pending && !shutdown_pending) {
- /* this is a memory leak, but I'll fix it later. */
- pid = ap_wait_or_timeout(&status, pconf);
+ ap_wait_or_timeout(&status, &pid, pconf);
- if (pid != NULL) {
- process_child_status(pid, status);
+ if (pid.pid != -1) {
+ process_child_status(&pid, status);
/* non-fatal death... note that it's gone in the scoreboard. */
- child_slot = find_child_by_pid(pid);
+ child_slot = find_child_by_pid(&pid);
if (child_slot >= 0) {
ap_mpmt_pthread_force_reset_connection_status(child_slot);
for (i = 0; i < ap_threads_per_child; i++)
@@ -1041,7 +1040,7 @@ static void server_main_loop(int remaining_children_to_start)
}
#ifdef APR_HAS_OTHER_CHILD
}
- else if (ap_reap_other_child(pid, status) == 0) {
+ else if (ap_reap_other_child(&pid, status) == 0) {
/* handled */
#endif
}
@@ -1052,7 +1051,7 @@ static void server_main_loop(int remaining_children_to_start)
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0,
ap_server_conf,
"long lost child came home! (pid %ld)",
- (long)pid->pid);
+ (long)pid.pid);
}
/* Don't perform idle maintenance when a child dies,
* only do it when there's a timeout. Remember only a
diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c
index 3da49bf355..7e24fcf488 100644
--- a/server/mpm/prefork/prefork.c
+++ b/server/mpm/prefork/prefork.c
@@ -1956,17 +1956,19 @@ int ap_mpm_run(ap_pool_t *_pconf, ap_pool_t *plog, server_rec *s)
int child_slot;
ap_wait_t status;
/* this is a memory leak, but I'll fix it later. */
- ap_proc_t *pid = ap_wait_or_timeout(&status, pconf);
+ ap_proc_t pid;
+
+ ap_wait_or_timeout(&status, &pid, pconf);
/* XXX: if it takes longer than 1 second for all our children
* to start up and get into IDLE state then we may spawn an
* extra child
*/
- if (pid != NULL) {
- process_child_status(pid, status);
+ if (pid.pid != -1) {
+ process_child_status(&pid, status);
/* non-fatal death... note that it's gone in the scoreboard. */
ap_sync_scoreboard_image();
- child_slot = find_child_by_pid(pid);
+ child_slot = find_child_by_pid(&pid);
if (child_slot >= 0) {
ap_prefork_force_reset_connection_status(child_slot);
(void) ap_update_child_status(child_slot, SERVER_DEAD,
@@ -1981,7 +1983,7 @@ int ap_mpm_run(ap_pool_t *_pconf, ap_pool_t *plog, server_rec *s)
}
#ifdef APR_HAS_OTHER_CHILD
}
- else if (ap_reap_other_child(pid, status) == 0) {
+ else if (ap_reap_other_child(&pid, status) == 0) {
/* handled */
#endif
}
@@ -1992,7 +1994,7 @@ int ap_mpm_run(ap_pool_t *_pconf, ap_pool_t *plog, server_rec *s)
*/
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING,
0, ap_server_conf,
- "long lost child came home! (pid %d)", pid->pid);
+ "long lost child came home! (pid %d)", pid.pid);
}
/* Don't perform idle maintenance when a child dies,
* only do it when there's a timeout. Remember only a
diff --git a/server/mpm_common.c b/server/mpm_common.c
index 57cea63254..c7c3dd1f90 100644
--- a/server/mpm_common.c
+++ b/server/mpm_common.c
@@ -176,11 +176,10 @@ void ap_reclaim_child_processes(int terminate)
#endif
static int wait_or_timeout_counter;
-ap_proc_t *ap_wait_or_timeout(ap_wait_t *status, ap_pool_t *p)
+void ap_wait_or_timeout(ap_wait_t *status, ap_proc_t *ret, ap_pool_t *p)
{
struct timeval tv;
ap_status_t rv;
- ap_proc_t *ret = ap_pcalloc(p, sizeof(*ret));
++wait_or_timeout_counter;
if (wait_or_timeout_counter == INTERVAL_OF_WRITABLE_PROBES) {
@@ -191,20 +190,22 @@ ap_proc_t *ap_wait_or_timeout(ap_wait_t *status, ap_pool_t *p)
}
rv = ap_wait_all_procs(ret, status, APR_NOWAIT, p);
if (ap_canonical_error(rv) == APR_EINTR) {
- return NULL;
+ ret->pid = -1;
+ return;
}
if (rv == APR_CHILD_DONE) {
- return ret;
+ return;
}
#ifdef NEED_WAITPID
if ((ret = reap_children(status)) > 0) {
- return ret;
+ return;
}
#endif
tv.tv_sec = SCOREBOARD_MAINTENANCE_INTERVAL / 1000000;
tv.tv_usec = SCOREBOARD_MAINTENANCE_INTERVAL % 1000000;
ap_select(0, NULL, NULL, NULL, &tv);
- return NULL;
+ ret->pid = -1;
+ return;
}