win32: introduce `do_with_retries` macro

Provide a macro that will allow us to run a function with posix-like
return values multiple times in a retry loop, with an optional cleanup
function called between invocations.
diff --git a/include/git2/errors.h b/include/git2/errors.h
index 3b746b7..71bff0f 100644
--- a/include/git2/errors.h
+++ b/include/git2/errors.h
@@ -53,6 +53,7 @@
 
 	GIT_PASSTHROUGH     = -30,	/**< Internal only */
 	GIT_ITEROVER        = -31,	/**< Signals end of iteration with iterator */
+	GIT_RETRY           = -32,	/**< Internal only */
 } git_error_code;
 
 /**
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 14f30eb..1dd6bff 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -157,6 +157,27 @@
 	}
 }
 
+GIT_INLINE(bool) last_error_retryable(void)
+{
+	int os_error = GetLastError();
+
+	return (os_error == ERROR_SHARING_VIOLATION ||
+		os_error == ERROR_ACCESS_DENIED);
+}
+
+#define do_with_retries(fn, cleanup) \
+	do {                                                             \
+		int __tries, __ret;                                          \
+		for (__tries = 0; __tries < 10; __tries++) {                 \
+			if (__tries && (__ret = (cleanup)) != 0)                 \
+				return __ret;                                        \
+			if ((__ret = (fn)) != GIT_RETRY)                         \
+				return __ret;                                        \
+			Sleep(5);                                                \
+		}                                                            \
+		return -1;                                                   \
+	} while (0)                                                      \
+
 /**
  * Truncate or extend file.
  *