aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compat/mingw.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/compat/mingw.c b/compat/mingw.c
index a7e1c6b47..9421a37c1 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -3,6 +3,8 @@
#include <conio.h>
#include "../strbuf.h"
+static const int delay[] = { 0, 1, 10, 20, 40 };
+
int err_win_to_posix(DWORD winerr)
{
int error = ENOSYS;
@@ -116,12 +118,38 @@ int err_win_to_posix(DWORD winerr)
return error;
}
+static inline int is_file_in_use_error(DWORD errcode)
+{
+ switch (errcode) {
+ case ERROR_SHARING_VIOLATION:
+ case ERROR_ACCESS_DENIED:
+ return 1;
+ }
+
+ return 0;
+}
+
#undef unlink
int mingw_unlink(const char *pathname)
{
+ int ret, tries = 0;
+
/* read-only files cannot be removed */
chmod(pathname, 0666);
- return unlink(pathname);
+ while ((ret = unlink(pathname)) == -1 && tries < ARRAY_SIZE(delay)) {
+ if (!is_file_in_use_error(GetLastError()))
+ break;
+ /*
+ * We assume that some other process had the source or
+ * destination file open at the wrong moment and retry.
+ * In order to give the other process a higher chance to
+ * complete its operation, we give up our time slice now.
+ * If we have to retry again, we do sleep a bit.
+ */
+ Sleep(delay[tries]);
+ tries++;
+ }
+ return ret;
}
#undef open
@@ -1257,7 +1285,6 @@ int mingw_rename(const char *pold, const char *pnew)
{
DWORD attrs, gle;
int tries = 0;
- static const int delay[] = { 0, 1, 10, 20, 40 };
/*
* Try native rename() first to get errno right.