Browse Source

Bug 1775: Keep trying to save configuration for up to 2 seconds when INI file is locked by another process

https://winscp.net/tracker/1775

Source commit: 682e051d1d05f6c5a043f8dac043146dedf67984
Martin Prikryl 6 years ago
parent
commit
b0bc42919c
1 changed files with 23 additions and 3 deletions
  1. 23 3
      source/core/HierarchicalStorage.cpp

+ 23 - 3
source/core/HierarchicalStorage.cpp

@@ -1560,13 +1560,33 @@ void __fastcall TIniFileStorage::Flush()
         SetFileAttributes(ApiPath(Storage).c_str(), Attr & ~FILE_ATTRIBUTE_READONLY);
       }
 
-      HANDLE Handle = CreateFile(ApiPath(Storage).c_str(), GENERIC_READ | GENERIC_WRITE,
-        0, NULL, CREATE_ALWAYS, Attr, 0);
+      HANDLE Handle;
+      int Error;
+      bool Retry;
+      int Trying = 0;
+      do
+      {
+        Error = 0;
+        Handle =
+          CreateFile(ApiPath(Storage).c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, Attr, 0);
+        if (Handle == INVALID_HANDLE_VALUE)
+        {
+          Error = GetLastError();
+        }
+        Retry = (Error == ERROR_SHARING_VIOLATION) && (Trying < 2000);
+        if (Retry)
+        {
+          const int Step = 100;
+          Sleep(Step);
+          Trying += Step;
+        }
+      }
+      while (Retry);
 
       if (Handle == INVALID_HANDLE_VALUE)
       {
         // "access denied" errors upon implicit saves to existing file are ignored
-        if (Explicit || !Exists || (GetLastError() != ERROR_ACCESS_DENIED))
+        if (Explicit || !Exists || (Error != ERROR_ACCESS_DENIED))
         {
           throw EOSExtException(FMTLOAD((Exists ? WRITE_ERROR : CREATE_FILE_ERROR), (Storage)));
         }