Pārlūkot izejas kodu

Bug fix: Failure when error occurs while another error is already being handled

Source commit: 4a23e7b719f5e2f9cfb8d917acf7ba53bc1ed433
Martin Prikryl 7 gadi atpakaļ
vecāks
revīzija
e1290d4986

+ 6 - 1
source/forms/CustomScpExplorer.cpp

@@ -206,6 +206,7 @@ __fastcall TCustomScpExplorerForm::TCustomScpExplorerForm(TComponent* Owner):
   FStandaloneEditing = false;
   FOnFeedSynchronizeError = NULL;
   FNeedSession = false;
+  FDoNotIdleCurrentTerminal = false;
 
   FEditorManager = new TEditorManager();
   FEditorManager->OnFileChange = ExecutedFileChanged;
@@ -1392,6 +1393,9 @@ void __fastcall TCustomScpExplorerForm::OperationComplete(
 void __fastcall TCustomScpExplorerForm::OperationProgress(
   TFileOperationProgressType & ProgressData)
 {
+  // For example, when calling TFileOperationProgressType::Suspend in TTerminal::QueryReopen,
+  // we cannot recurse back to TTerminal::Idle as that may detect another error, calling "suspend" again.
+  TAutoFlag Flag(FDoNotIdleCurrentTerminal);
   FileOperationProgress(ProgressData);
 }
 //---------------------------------------------------------------------------
@@ -1471,6 +1475,7 @@ void __fastcall TCustomScpExplorerForm::OperationFinished(
   bool Temp, const UnicodeString & FileName, Boolean Success,
   TOnceDoneOperation & OnceDoneOperation)
 {
+  TAutoFlag Flag(FDoNotIdleCurrentTerminal);
   DoOperationFinished(Operation, Side, Temp, FileName, Success,
     OnceDoneOperation);
 }
@@ -4322,7 +4327,7 @@ void __fastcall TCustomScpExplorerForm::Idle()
 
     // make sure that Idle is called before update queue, as it may invoke QueueEvent
     // that needs to know if queue view is visible (and it may be closed after queue update)
-    TTerminalManager::Instance()->Idle();
+    TTerminalManager::Instance()->Idle(FDoNotIdleCurrentTerminal);
   }
 
   if (FShowing)

+ 1 - 0
source/forms/CustomScpExplorer.h

@@ -326,6 +326,7 @@ protected:
   TDragDropFilesEx * FQueueDragDropFilesEx;
   TPoint FLastContextPopupScreenPoint;
   bool FRemoteDirViewWasFocused;
+  bool FDoNotIdleCurrentTerminal;
 
   virtual bool __fastcall CopyParamDialog(TTransferDirection Direction,
     TTransferType Type, bool Temp, TStrings * FileList,

+ 20 - 17
source/windows/TerminalManager.cpp

@@ -1384,7 +1384,7 @@ void __fastcall TTerminalManager::NewSession(bool /*FromSite*/, const UnicodeStr
   }
 }
 //---------------------------------------------------------------------------
-void __fastcall TTerminalManager::Idle()
+void __fastcall TTerminalManager::Idle(bool SkipCurrentTerminal)
 {
 
   if (FPendingConfigurationChange > 0) // optimization
@@ -1411,27 +1411,30 @@ void __fastcall TTerminalManager::Idle()
     TTerminal * Terminal = Terminals[Index];
     try
     {
-      TManagedTerminal * ManagedTerminal = dynamic_cast<TManagedTerminal *>(Terminal);
-      DebugAssert(ManagedTerminal != NULL);
-      // make sure Idle is called on the thread that runs the terminal
-      if (ManagedTerminal->TerminalThread != NULL)
+      if (!SkipCurrentTerminal || (Terminal != ActiveTerminal))
       {
-        ManagedTerminal->TerminalThread->Idle();
-      }
-      else
-      {
-        if (Terminal->Active)
+        TManagedTerminal * ManagedTerminal = dynamic_cast<TManagedTerminal *>(Terminal);
+        DebugAssert(ManagedTerminal != NULL);
+        // make sure Idle is called on the thread that runs the terminal
+        if (ManagedTerminal->TerminalThread != NULL)
         {
-          Terminal->Idle();
+          ManagedTerminal->TerminalThread->Idle();
+        }
+        else
+        {
+          if (Terminal->Active)
+          {
+            Terminal->Idle();
+          }
         }
-      }
 
-      if (Terminal->Active)
-      {
-        DebugAssert(Index < FQueues->Count);
-        if (Index < FQueues->Count)
+        if (Terminal->Active)
         {
-          reinterpret_cast<TTerminalQueue *>(FQueues->Items[Index])->Idle();
+          DebugAssert(Index < FQueues->Count);
+          if (Index < FQueues->Count)
+          {
+            reinterpret_cast<TTerminalQueue *>(FQueues->Items[Index])->Idle();
+          }
         }
       }
     }

+ 1 - 1
source/windows/TerminalManager.h

@@ -53,7 +53,7 @@ public:
   bool __fastcall CanOpenInPutty();
   void __fastcall OpenInPutty();
   void __fastcall NewSession(bool FromSite, const UnicodeString & SessionUrl, bool ReloadSessions = true, TForm * LinkedForm = NULL);
-  void __fastcall Idle();
+  void __fastcall Idle(bool SkipCurrentTerminal);
   UnicodeString __fastcall TerminalTitle(TTerminal * Terminal);
   void __fastcall HandleException(Exception * E);
   void __fastcall SaveWorkspace(TList * DataList);