summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorJustin Erenkrantz <jerenkrantz@apache.org>2005-08-11 01:03:38 +0200
committerJustin Erenkrantz <jerenkrantz@apache.org>2005-08-11 01:03:38 +0200
commitd971ca4ef87feae17c295d44b5100bc7d8e53855 (patch)
tree2b5b1dd9a9bb6011828b40cd627482b1e3428fe9 /modules
parentUpdate mod_dbd to API that hides apr_dbd_driver_t struct. (diff)
downloadapache2-d971ca4ef87feae17c295d44b5100bc7d8e53855.tar.xz
apache2-d971ca4ef87feae17c295d44b5100bc7d8e53855.zip
mod_disk_cache: Retry file rename up to three times to ameliorate race
condition with htcacheclean removing the directories underneath us. (Includes tweaks by Justin.) Suggested by: Graham Leggett Submitted by: Andreas Steinmetz <ast@domdv.de> Reviewed by: Justin Erenkrantz git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@231349 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules')
-rw-r--r--modules/cache/mod_disk_cache.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/modules/cache/mod_disk_cache.c b/modules/cache/mod_disk_cache.c
index 784b1371fb..57e61c6227 100644
--- a/modules/cache/mod_disk_cache.c
+++ b/modules/cache/mod_disk_cache.c
@@ -184,6 +184,33 @@ static void mkdir_structure(disk_cache_conf *conf, const char *file, apr_pool_t
}
}
+/* htcacheclean may remove directories underneath us.
+ * So, we'll try renaming three times at a cost of 0.002 seconds.
+ */
+static apr_status_t safe_file_rename(disk_cache_conf *conf,
+ const char *src, const char *dest,
+ apr_pool_t *pool)
+{
+ apr_status_t rv;
+
+ rv = apr_file_rename(src, dest, pool);
+
+ if (rv != APR_SUCCESS) {
+ int i;
+
+ for (i = 0; i < 2 && rv != APR_SUCCESS; i++) {
+ /* 1000 micro-seconds aka 0.001 seconds. */
+ apr_sleep(1000);
+
+ mkdir_structure(conf, dest, pool);
+
+ rv = apr_file_rename(src, dest, pool);
+ }
+ }
+
+ return rv;
+}
+
static apr_status_t file_cache_el_final(disk_cache_object_t *dobj,
request_rec *r)
{
@@ -795,7 +822,8 @@ static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info
dobj->tfd = NULL;
- rv = apr_file_rename(dobj->tempfile, dobj->hdrsfile, r->pool);
+ rv = safe_file_rename(conf, dobj->tempfile, dobj->hdrsfile,
+ r->pool);
if (rv != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, r->server,
"disk_cache: rename tempfile to varyfile failed: %s -> %s",
@@ -886,9 +914,8 @@ static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info
if (rv != APR_SUCCESS) {
mkdir_structure(conf, dobj->hdrsfile, r->pool);
}
-
- rv = apr_file_rename(dobj->tempfile, dobj->hdrsfile, r->pool);
+ rv = safe_file_rename(conf, dobj->tempfile, dobj->hdrsfile, r->pool);
if (rv != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
"disk_cache: rename tempfile to hdrsfile failed: %s -> %s",