diff options
author | stoddard <stoddard@13f79535-47bb-0310-9956-ffa450edef68> | 2002-11-12 04:24:51 +0000 |
---|---|---|
committer | stoddard <stoddard@13f79535-47bb-0310-9956-ffa450edef68> | 2002-11-12 04:24:51 +0000 |
commit | 617c9818abf5f1b8dce3b9b0267f63150441aef5 (patch) | |
tree | e8e1ca855982c6862839917c9f3f41e328d1e387 /memory | |
parent | 8c2720e28a3e61fa879bf8d477940473e4293d6f (diff) | |
download | libapr-617c9818abf5f1b8dce3b9b0267f63150441aef5.tar.gz |
Update free_proc_chain timeout algorithm from a static 3 second timeout
to an exponentiallly growing timeout.
PR: 7617
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@64016 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'memory')
-rw-r--r-- | memory/unix/apr_pools.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/memory/unix/apr_pools.c b/memory/unix/apr_pools.c index 2a7fdf8fc..5538b0269 100644 --- a/memory/unix/apr_pools.c +++ b/memory/unix/apr_pools.c @@ -86,6 +86,15 @@ #define BOUNDARY_INDEX 12 #define BOUNDARY_SIZE (1 << BOUNDARY_INDEX) +/* + * Timing constants for killing subprocesses + * There is a total 3-second delay between sending a SIGINT + * and sending of the final SIGKILL. + * TIMEOUT_INTERVAL should be set to TIMEOUT_USECS / 64 + * for the exponetial timeout alogrithm. + */ +#define TIMEOUT_USECS 3000000 +#define TIMEOUT_INTERVAL 46875 /* * Allocator @@ -2031,6 +2040,7 @@ static void free_proc_chain(struct process_chain *procs) */ struct process_chain *pc; int need_timeout = 0; + apr_time_t timeout_interval; if (!procs) return; /* No work. Whew! */ @@ -2071,9 +2081,32 @@ static void free_proc_chain(struct process_chain *procs) } } - /* Sleep only if we have to... */ - if (need_timeout) - apr_sleep(apr_time_from_sec(3)); + /* Sleep only if we have to. The sleep algorithm grows + * by a factor of two on each iteration. TIMEOUT_INTERVAL + * is equal to TIMEOUT_USECS / 64. + */ + if (need_timeout) { + timeout_interval = TIMEOUT_INTERVAL; + apr_sleep(timeout_interval); + } + while (need_timeout) { + need_timeout = 0; + /* check the status of the subprocesses */ + for (pc = procs; pc; pc = pc->next) { + if (pc->kill_how == APR_KILL_AFTER_TIMEOUT && + apr_proc_wait(pc->pid, NULL, NULL, APR_NOWAIT) != APR_CHILD_NOTDONE) + pc->kill_how = APR_KILL_NEVER; /* subprocess has exited */ + else + need_timeout = 1; /* subprocess is still active */ + } + if (need_timeout) { + apr_sleep(timeout_interval); + timeout_interval *= 2; + if (timeout_interval >= TIMEOUT_USECS) { + break; + } + } + } /* OK, the scripts we just timed out for have had a chance to clean up * --- now, just get rid of them, and also clean up the system accounting |