Alien-SVN
view release on metacpan or search on metacpan
src/subversion/subversion/libsvn_subr/io.c view on Meta::CPAN
#include <stdio.h>
#ifndef WIN32
#include <unistd.h>
#endif
#ifndef APR_STATUS_IS_EPERM
#include <errno.h>
#ifdef EPERM
#define APR_STATUS_IS_EPERM(s) ((s) == EPERM)
#else
#define APR_STATUS_IS_EPERM(s) (0)
#endif
#endif
#include <apr_lib.h>
#include <apr_pools.h>
#include <apr_file_io.h>
#include <apr_file_info.h>
#include <apr_general.h>
#include <apr_strings.h>
#include <apr_portable.h>
#include <apr_md5.h>
#ifdef WIN32
#include <arch/win32/apr_arch_file_io.h>
#endif
#include "svn_hash.h"
#include "svn_types.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_string.h"
#include "svn_error.h"
#include "svn_io.h"
#include "svn_pools.h"
#include "svn_utf.h"
#include "svn_config.h"
#include "svn_private_config.h"
#include "svn_ctype.h"
#include "private/svn_atomic.h"
#include "private/svn_io_private.h"
#define SVN_SLEEP_ENV_VAR "SVN_I_LOVE_CORRUPTED_WORKING_COPIES_SO_DISABLE_SLEEP_FOR_TIMESTAMPS"
/*
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.
Another reason for retrying delete operations on Windows
is that they are asynchronous -- the file or directory is not
actually deleted until the last handle to it is closed. The
retry loop cannot completely solve this problem either, but can
help mitigate it.
*/
#define RETRY_MAX_ATTEMPTS 100
#define RETRY_INITIAL_SLEEP 1000
#define RETRY_MAX_SLEEP 128000
#define RETRY_LOOP(err, expr, retry_test, sleep_test) \
do \
{ \
apr_status_t os_err = APR_TO_OS_ERROR(err); \
int sleep_count = RETRY_INITIAL_SLEEP; \
int retries; \
for (retries = 0; \
retries < RETRY_MAX_ATTEMPTS && (retry_test); \
os_err = APR_TO_OS_ERROR(err)) \
{ \
if (sleep_test) \
{ \
++retries; \
apr_sleep(sleep_count); \
if (sleep_count < RETRY_MAX_SLEEP) \
sleep_count *= 2; \
} \
(err) = (expr); \
} \
} \
while (0)
#if defined(EDEADLK) && APR_HAS_THREADS
#define FILE_LOCK_RETRY_LOOP(err, expr) \
RETRY_LOOP(err, \
expr, \
(APR_STATUS_IS_EINTR(err) || os_err == EDEADLK), \
(!APR_STATUS_IS_EINTR(err)))
#else
#define FILE_LOCK_RETRY_LOOP(err, expr) \
RETRY_LOOP(err, \
expr, \
(APR_STATUS_IS_EINTR(err)), \
0)
#endif
#ifndef WIN32_RETRY_LOOP
#if defined(WIN32) && !defined(SVN_NO_WIN32_RETRY_LOOP)
#define WIN32_RETRY_LOOP(err, expr) \
RETRY_LOOP(err, expr, (os_err == ERROR_ACCESS_DENIED \
|| os_err == ERROR_SHARING_VIOLATION \
|| os_err == ERROR_DIR_NOT_EMPTY), \
1)
#else
#define WIN32_RETRY_LOOP(err, expr) ((void)0)
#endif
#endif
/* Forward declaration */
static apr_status_t
dir_is_empty(const char *dir, apr_pool_t *pool);
static APR_INLINE svn_error_t *
( run in 0.573 second using v1.01-cache-2.11-cpan-d7f47b0818f )