summaryrefslogtreecommitdiff
path: root/src/win32
diff options
context:
space:
mode:
authorJan Melcher <info@yogularm.de>2014-03-27 12:42:44 +0100
committerJan Melcher <info@yogularm.de>2014-03-27 12:42:44 +0100
commit2873a862fd1899909424b60b44fa0680851a60f6 (patch)
tree37a3d14c7915f90ea2d7deb7c0ec50c37de2e514 /src/win32
parent041fad4aac106650f00b7c445675f1c4bb8cfd53 (diff)
downloadlibgit2-2873a862fd1899909424b60b44fa0680851a60f6.tar.gz
Retry renaming files on Access Denied errors
When a file is open for reading (without shared-delete permission), and then a different thread/process called p_rename, that would fail, even if the file was only open for reading for a few milliseconds. This change lets p_rename wait up to 50ms for the file to be closed by the reader. Applies only to win32. This is especially important for git_filebuf_commit, because writes should not fail if the file is read simultaneously. Fixes #2207
Diffstat (limited to 'src/win32')
-rw-r--r--src/win32/posix_w32.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 18f717b0f..6f2931880 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -467,10 +467,31 @@ int p_rename(const char *from, const char *to)
{
git_win32_path wfrom;
git_win32_path wto;
+ int rename_tries;
+ int rename_succeeded;
+ int error;
git_win32_path_from_c(wfrom, from);
git_win32_path_from_c(wto, to);
- return MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) ? 0 : -1;
+
+ /* wait up to 50ms if file is locked by another thread or process */
+ rename_tries = 0;
+ rename_succeeded = 0;
+ while (rename_tries < 10) {
+ if (MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) != 0) {
+ rename_succeeded = 1;
+ break;
+ }
+
+ error = GetLastError();
+ if (error == ERROR_SHARING_VIOLATION || error == ERROR_ACCESS_DENIED) {
+ Sleep(5);
+ rename_tries++;
+ } else
+ break;
+ }
+
+ return rename_succeeded ? 0 : -1;
}
int p_recv(GIT_SOCKET socket, void *buffer, size_t length, int flags)