diff options
author | Vladislav Vaintroub <wlad@mariadb.com> | 2022-12-05 15:07:50 +0100 |
---|---|---|
committer | Vladislav Vaintroub <wlad@mariadb.com> | 2022-12-07 14:26:10 +0100 |
commit | d360fa6fa897d9556dc3813e6f3366e01df8e715 (patch) | |
tree | ced1943c1b3dde42d6438655d0ab86f8ca2e3e97 /mysys/my_winfile.c | |
parent | 2beede9ba48c270d94662f66c49c5129caaa1e8b (diff) | |
download | mariadb-git-d360fa6fa897d9556dc3813e6f3366e01df8e715.tar.gz |
MDEV-30162 Fix occasional "Permission denied" on Windows caused by buggy 3rd party
Add retry logic for CreateFile, DeleteFile, or MoveFile
when GetLastError() is ERROR_SHARING_VIOLATION.
Diffstat (limited to 'mysys/my_winfile.c')
-rw-r--r-- | mysys/my_winfile.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/mysys/my_winfile.c b/mysys/my_winfile.c index 0baca6d62d7..a2b621c7aa3 100644 --- a/mysys/my_winfile.c +++ b/mysys/my_winfile.c @@ -102,6 +102,42 @@ static int my_get_open_flags(File fd) DBUG_RETURN(my_file_info[fd].oflag); } +/* + CreateFile with retry logic. + + Uses retries, to avoid or reduce CreateFile errors + with ERROR_SHARING_VIOLATION, in case the file is opened + by another process, which used incompatible sharing + flags when opening. + + See Windows' CreateFile() documentation for details. +*/ +static HANDLE my_create_file_with_retries( + LPCSTR lpFileName, DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile) +{ + int retries; + DBUG_INJECT_FILE_SHARING_VIOLATION(lpFileName); + + for (retries = FILE_SHARING_VIOLATION_RETRIES;;) + { + HANDLE h= CreateFile(lpFileName, dwDesiredAccess, dwShareMode, + lpSecurityAttributes, dwCreationDisposition, + dwFlagsAndAttributes, hTemplateFile); + DBUG_CLEAR_FILE_SHARING_VIOLATION(); + + if (h != INVALID_HANDLE_VALUE || + GetLastError() != ERROR_SHARING_VIOLATION || --retries == 0) + return h; + + Sleep(FILE_SHARING_VIOLATION_DELAY_MS); + } + return INVALID_HANDLE_VALUE; +} /* Open a file with sharing. Similar to _sopen() from libc, but allows managing @@ -247,7 +283,7 @@ File my_win_sopen(const char *path, int oflag, int shflag, int pmode) fileattrib|= FILE_FLAG_RANDOM_ACCESS; /* try to open/create the file */ - if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes, + if ((osfh= my_create_file_with_retries(path, fileaccess, fileshare, &SecurityAttributes, filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE) { DWORD last_error= GetLastError(); |