[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: svn 0.34.0, 0.35.1 windows access is denied on delete directory

From: D.J. Heap <dj_at_shadyvale.net>
Date: 2004-01-16 05:47:21 CET

Philip Martin wrote:
[snip]

I was able to get your patch working with a bit of tweaking, but I ran
into some warnings and as I was tinkering I came up with this patch and
thought I'd run it past you and see if it's acceptable -- it folds all
of the loops into one preprocessor macro, but it *is* kind of an ugly
preprocessor macro, which may not be acceptable...? On Windows it
compiles and runs and solves the 'access denied' problems that I am able
to recreate with our A/V software.

Log:

Factor the Window's retry loops into a macro and add the loops to
a couple of more places where 'access denied' errors have been
reported.

* subversion\libsvn_subr\io.c
   (svn_io_file_rename, svn_io_remove_file, svn_io_remove_dir,
    svn_io_dir_remove_nonrecursive): Factor out the Windows
    retry loop into a macro and add it to the directory
    removal functions.

Index: subversion/libsvn_subr/io.c
===================================================================
--- subversion/libsvn_subr/io.c (revision 8339)
+++ subversion/libsvn_subr/io.c (working copy)
@@ -41,6 +41,38 @@
 #include "svn_config.h"
 
 
+/*
+ Windows is 'aided' by a number of types of applications that
+ follow other applications around and open up files they have
+ changed for various reasons (the most intrusive are virus
+ scanners). So, if one of these other apps has glommed onto
+ our file we may get an 'access denied' error.
+
+ This retry loop does not completely solve the problem (who
+ knows how long the other app is going to hold onto it for), but
+ goes a long way towards minimizing it. It is not an infinite
+ loop because there might really be an error.
+*/
+#ifdef WIN32
+#define WIN32_RETRY_LOOP(err, expr) \
+ { \
+ int retries = 0; \
+ int sleep_count = 1000; \
+ \
+ for ( retries = 0; \
+ APR_TO_OS_ERROR (err) == ERROR_ACCESS_DENIED && retries < 100; \
+ ++retries ) \
+ { \
+ apr_sleep (sleep_count); \
+ if (sleep_count < 128000) \
+ sleep_count *= 2; \
+ err = expr; \
+ } \
+ }
+#else
+#define WIN32_RETRY_LOOP(err, expr)
+#endif
+
 /* Helper for svn_io_check_path() and svn_io_check_resolved_path();
    essentially the same semantics as those two, with the obvious
    interpretation for RESOLVE_SYMLINKS. */
@@ -998,36 +1030,8 @@
   SVN_ERR (svn_path_cstring_from_utf8 (&path_apr, path, pool));
 
   apr_err = apr_file_remove (path_apr, pool);
+ WIN32_RETRY_LOOP (apr_err, apr_file_remove (path_apr, pool));
 
-#ifdef WIN32
- /*
- Windows is 'aided' by a number of types of applications that
- follow other applications around and open up files they have
- changed for various reasons (the most intrusive are virus
- scanners). So, if one of these other apps has glommed onto
- our file we may get an 'access denied' error.
-
- This retry loop does not completely solve the problem (who
- knows how long the other app is going to hold onto it for), but
- goes a long way towards minimizing it. It is not an infinite
- loop because there might really be an error.
- */
- {
- int retries = 0;
- int sleep_count = 1000;
-
- for ( retries = 0;
- APR_TO_OS_ERROR (apr_err) == ERROR_ACCESS_DENIED && retries < 100;
- ++retries )
- {
- apr_sleep (sleep_count);
- if (sleep_count < 128000)
- sleep_count *= 2;
- apr_err = apr_file_remove (path_apr, pool);
- }
- }
-#endif /* WIN32 */
-
   if (apr_err)
     return svn_error_wrap_apr (apr_err, "Can't remove file '%s'", path);
 
@@ -1109,6 +1113,7 @@
     return svn_error_wrap_apr (status, "Error closing directory '%s'", path);
 
   status = apr_dir_remove (path_apr, subpool);
+ WIN32_RETRY_LOOP (status, apr_dir_remove (path_apr, subpool));
   if (status)
     return svn_error_wrap_apr (status, "Can't remove '%s'", path);
 
@@ -1746,36 +1751,9 @@
   SVN_ERR (svn_path_cstring_from_utf8 (&to_path_apr, to_path, pool));
 
   status = apr_file_rename (from_path_apr, to_path_apr, pool);
+ WIN32_RETRY_LOOP (status,
+ apr_file_rename (from_path_apr, to_path_apr, pool));
 
-#ifdef WIN32
- /*
- Windows is 'aided' by a number of types of applications that
- follow other applications around and open up files they have
- changed for various reasons (the most intrusive are virus
- scanners). So, if one of these other apps has glommed onto
- our file we may get an 'access denied' error.
-
- This retry loop does not completely solve the problem (who
- knows how long the other app is going to hold onto it for), but
- goes a long way towards minimizing it. It is not an infinite
- loop because there might really be an error.
- */
- {
- int retries = 0;
- int sleep_count = 1000;
-
- for ( retries = 0;
- APR_TO_OS_ERROR (status) == ERROR_ACCESS_DENIED && retries < 100;
- ++retries )
- {
- apr_sleep (sleep_count);
- if (sleep_count < 128000)
- sleep_count *= 2;
- status = apr_file_rename (from_path_apr, to_path_apr, pool);
- }
- }
-#endif /* WIN32 */
-
   if (status)
     return svn_error_wrap_apr (status, "Can't move '%s' to '%s'",
                                from_path, to_path);
@@ -1859,6 +1837,7 @@
   SVN_ERR (svn_path_cstring_from_utf8 (&dirname_apr, dirname, pool));
 
   status = apr_dir_remove (dirname_apr, pool);
+ WIN32_RETRY_LOOP (status, apr_dir_remove (dirname_apr, pool));
   if (status)
     return svn_error_wrap_apr (status, "Can't remove directory '%s'", dirname);
 

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri Jan 16 05:48:03 2004

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.