Browse Source

Bug 1169: Do not indefinitely retry transfer with FTP protocol when opening transfer channel is failing

https://winscp.net/tracker/1169

Source commit: fdf6efb83b9c71e000be8bebf2fb5b1e8e99384f
Martin Prikryl 9 years ago
parent
commit
5678cc28c7
4 changed files with 59 additions and 10 deletions
  1. 3 2
      source/core/FtpFileSystem.cpp
  2. 1 0
      source/core/FtpFileSystem.h
  3. 49 7
      source/core/Terminal.cpp
  4. 6 1
      source/core/Terminal.h

+ 3 - 2
source/core/FtpFileSystem.cpp

@@ -1450,6 +1450,7 @@ void __fastcall TFTPFileSystem::DoFileTransferProgress(__int64 TransferSize,
   if (DebugAlwaysTrue(Diff >= 0))
   {
     OperationProgress->AddTransfered(Diff);
+    FFileTransferAny = true;
   }
 
   if (OperationProgress->Cancel != csContinue)
@@ -1573,7 +1574,7 @@ void __fastcall TFTPFileSystem::SinkRobust(const UnicodeString FileName,
   // the same in TSFTPFileSystem
 
   TDownloadSessionAction Action(FTerminal->ActionLog);
-  TRobustOperationLoop RobustLoop(FTerminal, OperationProgress);
+  TRobustOperationLoop RobustLoop(FTerminal, OperationProgress, &FFileTransferAny);
 
   do
   {
@@ -1871,7 +1872,7 @@ void __fastcall TFTPFileSystem::SourceRobust(const UnicodeString FileName,
   // the same in TSFTPFileSystem
 
   TUploadSessionAction Action(FTerminal->ActionLog);
-  TRobustOperationLoop RobustLoop(FTerminal, OperationProgress);
+  TRobustOperationLoop RobustLoop(FTerminal, OperationProgress, &FFileTransferAny);
 
   do
   {

+ 1 - 0
source/core/FtpFileSystem.h

@@ -290,6 +290,7 @@ private:
   __int64 FBytesAvailable;
   bool FBytesAvailableSuppoted;
   bool FMVS;
+  bool FFileTransferAny;
   mutable UnicodeString FOptionScratch;
 };
 //---------------------------------------------------------------------------

+ 49 - 7
source/core/Terminal.cpp

@@ -517,18 +517,54 @@ void __fastcall TCallbackGuard::Verify()
 }
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
-TRobustOperationLoop::TRobustOperationLoop(TTerminal * Terminal, TFileOperationProgressType * OperationProgress) :
+TRobustOperationLoop::TRobustOperationLoop(TTerminal * Terminal, TFileOperationProgressType * OperationProgress, bool * AnyTransfer) :
   FTerminal(Terminal),
   FOperationProgress(OperationProgress),
-  FRetry(false)
+  FRetry(false),
+  FAnyTransfer(AnyTransfer)
 {
+  if (FAnyTransfer != NULL)
+  {
+    FPrevAnyTransfer = *FAnyTransfer;
+    *FAnyTransfer = false;
+    FStart = Now();
+  }
+}
+//---------------------------------------------------------------------------
+TRobustOperationLoop::~TRobustOperationLoop()
+{
+  if (FAnyTransfer != NULL)
+  {
+    *FAnyTransfer = FPrevAnyTransfer;
+  }
 }
 //---------------------------------------------------------------------------
 bool TRobustOperationLoop::TryReopen(Exception & E)
 {
-  FRetry =
-    !FTerminal->Active &&
-    FTerminal->QueryReopen(&E, ropNoReadDirectory, FOperationProgress);
+  FRetry = !FTerminal->Active;
+  if (FRetry)
+  {
+    if (FAnyTransfer != NULL)
+    {
+      // if there was any transfer, reset the global timestamp
+      if (*FAnyTransfer)
+      {
+        FStart = Now();
+        FPrevAnyTransfer = true;
+        *FAnyTransfer = false;
+      }
+      else
+      {
+        FRetry = FTerminal->ContinueReopen(FStart);
+      }
+    }
+
+    if (FRetry)
+    {
+      FRetry =
+        FTerminal->QueryReopen(&E, ropNoReadDirectory, FOperationProgress);
+    }
+  }
   return FRetry;
 }
 //---------------------------------------------------------------------------
@@ -1651,6 +1687,13 @@ bool __fastcall TTerminal::DoQueryReopen(Exception * E)
   return Result;
 }
 //---------------------------------------------------------------------------
+bool __fastcall TTerminal::ContinueReopen(TDateTime Start)
+{
+  return
+    (Configuration->SessionReopenTimeout == 0) ||
+    (int(double(Now() - Start) * MSecsPerDay) < Configuration->SessionReopenTimeout);
+}
+//---------------------------------------------------------------------------
 bool __fastcall TTerminal::QueryReopen(Exception * E, int Params,
   TFileOperationProgressType * OperationProgress)
 {
@@ -1672,8 +1715,7 @@ bool __fastcall TTerminal::QueryReopen(Exception * E, int Params,
         if (!Active)
         {
           Result =
-            ((Configuration->SessionReopenTimeout == 0) ||
-             (int(double(Now() - Start) * MSecsPerDay) < Configuration->SessionReopenTimeout)) &&
+            ContinueReopen(Start) &&
             DoQueryReopen(&E);
         }
         else

+ 6 - 1
source/core/Terminal.h

@@ -489,6 +489,7 @@ public:
     TFileOperationProgressType * OperationProgress, const UnicodeString Message,
     bool AllowSkip, UnicodeString SpecialRetry = L"", UnicodeString HelpKeyword = L"");
   TUsableCopyParamAttrs __fastcall UsableCopyParamAttrs(int Params);
+  bool __fastcall ContinueReopen(TDateTime Start);
   bool __fastcall QueryReopen(Exception * E, int Params,
     TFileOperationProgressType * OperationProgress);
   UnicodeString __fastcall PeekCurrentDirectory();
@@ -735,7 +736,8 @@ struct TSpaceAvailable
 class TRobustOperationLoop
 {
 public:
-  TRobustOperationLoop(TTerminal * Terminal, TFileOperationProgressType * OperationProgress);
+  TRobustOperationLoop(TTerminal * Terminal, TFileOperationProgressType * OperationProgress, bool * AnyTransfer = NULL);
+  ~TRobustOperationLoop();
   bool TryReopen(Exception & E);
   bool ShouldRetry();
   bool Retry();
@@ -744,6 +746,9 @@ private:
   TTerminal * FTerminal;
   TFileOperationProgressType * FOperationProgress;
   bool FRetry;
+  bool * FAnyTransfer;
+  bool FPrevAnyTransfer;
+  TDateTime FStart;
 };
 //---------------------------------------------------------------------------
 #endif