diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2017-07-18 14:44:29 -0700 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2017-07-26 10:41:03 +0100 |
commit | bc35fd4b03fc770b574088969dabf07243510cfb (patch) | |
tree | d20670b04c3705387823f5e15c5f1118d51c311e | |
parent | 192a87e1fe68099beceaa2c8674a7a2e6587f2e7 (diff) | |
download | libgit2-bc35fd4b03fc770b574088969dabf07243510cfb.tar.gz |
win32: provide fast-path for retrying filesystem operationsethomson/win32_remediate
When using the `do_with_retries` macro for retrying filesystem
operations in the posix emulation layer, allow the remediation function
to return `GIT_RETRY`, meaning that the error was believed to be
remediated, and the operation should be retried immediately, without
a sleep.
This is a slightly more general solution to the problem fixed in #4312.
-rw-r--r-- | src/win32/posix_w32.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index 32fafa8ed..e744f4ffb 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -162,12 +162,15 @@ GIT_INLINE(bool) last_error_retryable(void) #define do_with_retries(fn, remediation) \ do { \ - int __tries, __ret; \ - for (__tries = 0; __tries < git_win32__retries; __tries++) { \ - if (__tries && (__ret = (remediation)) != 0) \ - return __ret; \ + int __retry, __ret; \ + for (__retry = git_win32__retries; __retry; __retry--) { \ if ((__ret = (fn)) != GIT_RETRY) \ return __ret; \ + if (__retry > 1 && (__ret = (remediation)) != 0) { \ + if (__ret == GIT_RETRY) \ + continue; \ + return __ret; \ + } \ Sleep(5); \ } \ return -1; \ @@ -186,7 +189,7 @@ static int ensure_writable(wchar_t *path) if (!SetFileAttributesW(path, (attrs & ~FILE_ATTRIBUTE_READONLY))) goto on_error; - return 0; + return GIT_RETRY; on_error: set_errno(); @@ -243,11 +246,6 @@ GIT_INLINE(int) unlink_once(const wchar_t *path) if (DeleteFileW(path)) return 0; - set_errno(); - - if (errno == EACCES && ensure_writable(path) == 0 && DeleteFileW(path)) - return 0; - if (last_error_retryable()) return GIT_RETRY; @@ -262,7 +260,7 @@ int p_unlink(const char *path) if (git_win32_path_from_utf8(wpath, path) < 0) return -1; - do_with_retries(unlink_once(wpath), 0); + do_with_retries(unlink_once(wpath), ensure_writable(wpath)); } int p_fsync(int fd) |