Skip to content

Commit bc35fd4

Browse files
committed
win32: provide fast-path for retrying filesystem operations
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 libgit2#4312.
1 parent 192a87e commit bc35fd4

File tree

1 file changed

+9
-11
lines changed

1 file changed

+9
-11
lines changed

src/win32/posix_w32.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -162,12 +162,15 @@ GIT_INLINE(bool) last_error_retryable(void)
162162

163163
#define do_with_retries(fn, remediation) \
164164
do { \
165-
int __tries, __ret; \
166-
for (__tries = 0; __tries < git_win32__retries; __tries++) { \
167-
if (__tries && (__ret = (remediation)) != 0) \
168-
return __ret; \
165+
int __retry, __ret; \
166+
for (__retry = git_win32__retries; __retry; __retry--) { \
169167
if ((__ret = (fn)) != GIT_RETRY) \
170168
return __ret; \
169+
if (__retry > 1 && (__ret = (remediation)) != 0) { \
170+
if (__ret == GIT_RETRY) \
171+
continue; \
172+
return __ret; \
173+
} \
171174
Sleep(5); \
172175
} \
173176
return -1; \
@@ -186,7 +189,7 @@ static int ensure_writable(wchar_t *path)
186189
if (!SetFileAttributesW(path, (attrs & ~FILE_ATTRIBUTE_READONLY)))
187190
goto on_error;
188191

189-
return 0;
192+
return GIT_RETRY;
190193

191194
on_error:
192195
set_errno();
@@ -243,11 +246,6 @@ GIT_INLINE(int) unlink_once(const wchar_t *path)
243246
if (DeleteFileW(path))
244247
return 0;
245248

246-
set_errno();
247-
248-
if (errno == EACCES && ensure_writable(path) == 0 && DeleteFileW(path))
249-
return 0;
250-
251249
if (last_error_retryable())
252250
return GIT_RETRY;
253251

@@ -262,7 +260,7 @@ int p_unlink(const char *path)
262260
if (git_win32_path_from_utf8(wpath, path) < 0)
263261
return -1;
264262

265-
do_with_retries(unlink_once(wpath), 0);
263+
do_with_retries(unlink_once(wpath), ensure_writable(wpath));
266264
}
267265

268266
int p_fsync(int fd)

0 commit comments

Comments
 (0)