You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by bl...@apache.org on 2011/02/01 23:34:46 UTC
svn commit: r1066249 - /subversion/trunk/subversion/libsvn_subr/io.c
Author: blair
Date: Tue Feb 1 22:34:45 2011
New Revision: 1066249
URL: http://svn.apache.org/viewvc?rev=1066249&view=rev
Log:
Getting a lock on a file using fcntl(F_SETLKW) may also return an
EINTR, so in addition to retrying with sleeps if a EDEADLK is
returned, retry without sleeps if an EINTR is returned.
* subversion/libsvn_subr/io.c
(RETRY_LOOP):
Add another argument, a test if apr_sleep() should be called.
(FILE_LOCK_RETRY_LOOP):
Renamed from EDEADLK_RETRY_LOOP.
Now always define FILE_LOCK_RETRY_LOOP that will retry and only
define different versions of EDEADLK is available.
Update all callers.
(WIN32_RETRY_LOOP):
Pass 1 as the new sleep test argument to RETRY_LOOP.
Modified:
subversion/trunk/subversion/libsvn_subr/io.c
Modified: subversion/trunk/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/io.c?rev=1066249&r1=1066248&r2=1066249&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/io.c (original)
+++ subversion/trunk/subversion/libsvn_subr/io.c Tue Feb 1 22:34:45 2011
@@ -85,29 +85,38 @@
#define RETRY_INITIAL_SLEEP 1000
#define RETRY_MAX_SLEEP 128000
-#define RETRY_LOOP(err, expr, test) \
+#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 && (test); \
+ retries < RETRY_MAX_ATTEMPTS && (retry_test); \
++retries, os_err = APR_TO_OS_ERROR(err)) \
{ \
- apr_sleep(sleep_count); \
- if (sleep_count < RETRY_MAX_SLEEP) \
- sleep_count *= 2; \
+ if (sleep_test) \
+ { \
+ apr_sleep(sleep_count); \
+ if (sleep_count < RETRY_MAX_SLEEP) \
+ sleep_count *= 2; \
+ } \
(err) = (expr); \
} \
} \
while (0)
#if defined(EDEADLK) && APR_HAS_THREADS
-#define EDEADLK_RETRY_LOOP(err, expr) \
- RETRY_LOOP(err, expr, (os_err == EDEADLK))
+#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 EDEADLK_RETRY_LOOP(err, expr) ((void)0)
+ RETRY_LOOP(err, \
+ expr, \
+ (APR_STATUS_IS_EINTR(err)), \
+ 0)
#endif
#ifndef WIN32_RETRY_LOOP
@@ -115,7 +124,8 @@
#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))
+ || os_err == ERROR_DIR_NOT_EMPTY), \
+ 1)
#else
#define WIN32_RETRY_LOOP(err, expr) ((void)0)
#endif
@@ -1718,7 +1728,7 @@ svn_io_file_lock2(const char *lock_file,
thread 2: try to get lock in B *** deadlock ***
Retry for a while for the deadlock to clear. */
- EDEADLK_RETRY_LOOP(apr_err, apr_file_lock(lockfile_handle, locktype));
+ FILE_LOCK_RETRY_LOOP(apr_err, apr_file_lock(lockfile_handle, locktype));
if (apr_err)
{