Browse Source

Bug 1483: Failure when logging fails for background session or during log in

https://winscp.net/tracker/1483
(cherry picked from commit bf15e6aba69ae693a8507e1d93865ebb66605f92)

Source commit: 544106d5f854a60a4174c599c73cfc253582114f
Martin Prikryl 9 years ago
parent
commit
dcff949251

+ 4 - 2
source/core/SessionInfo.cpp

@@ -870,6 +870,8 @@ void __fastcall TSessionLog::OpenLogFile()
     catch (Exception & E)
     {
       AddException(&E);
+      // not to deadlock with TSessionLog::ReflectSettings invoked by FConfiguration->LogFileName setter above
+      TUnguard Unguard(FCriticalSection);
       FUI->HandleExtendedException(&E);
     }
   }
@@ -1003,8 +1005,6 @@ UnicodeString __fastcall EnumName(T Value, UnicodeString Names)
 //---------------------------------------------------------------------------
 void __fastcall TSessionLog::DoAddStartupInfo(TSessionData * Data)
 {
-  TGuard Guard(FCriticalSection);
-
   BeginUpdate();
   try
   {
@@ -1531,6 +1531,8 @@ void __fastcall TActionLog::OpenLogFile()
       {
         if (FUI != NULL)
         {
+          // not to deadlock with TSessionLog::ReflectSettings invoked by FConfiguration->LogFileName setter above
+          TUnguard Unguard(FCriticalSection);
           FUI->HandleExtendedException(&E);
         }
       }

+ 37 - 1
source/windows/TerminalManager.cpp

@@ -72,6 +72,9 @@ __fastcall TTerminalManager::TTerminalManager() :
   FAuthenticateForm = NULL;
   FTaskbarList = NULL;
   FAuthenticating = 0;
+  FMainThread = GetCurrentThreadId();
+  FChangeSection.reset(new TCriticalSection());
+  FPendingConfigurationChange = 0;
 
   FApplicationsEvents.reset(new TApplicationEvents(Application));
   FApplicationsEvents->OnException = ApplicationException;
@@ -1158,7 +1161,7 @@ void __fastcall TTerminalManager::QueueEvent(TTerminalQueue * Queue, TQueueEvent
   FQueueEvents.push_back(std::make_pair(Queue, Event));
 }
 //---------------------------------------------------------------------------
-void __fastcall TTerminalManager::ConfigurationChange(TObject * /*Sender*/)
+void __fastcall TTerminalManager::DoConfigurationChange()
 {
   DebugAssert(Configuration);
   DebugAssert(Configuration == WinConfiguration);
@@ -1179,6 +1182,19 @@ void __fastcall TTerminalManager::ConfigurationChange(TObject * /*Sender*/)
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TTerminalManager::ConfigurationChange(TObject * /*Sender*/)
+{
+  if (FMainThread == GetCurrentThreadId())
+  {
+    DoConfigurationChange();
+  }
+  else
+  {
+    TGuard Guard(FChangeSection.get());
+    FPendingConfigurationChange++;
+  }
+}
+//---------------------------------------------------------------------------
 void __fastcall TTerminalManager::TerminalReady()
 {
   ScpExplorer->Terminal = ActiveTerminal;
@@ -1337,6 +1353,26 @@ void __fastcall TTerminalManager::NewSession(bool /*FromSite*/, const UnicodeStr
 //---------------------------------------------------------------------------
 void __fastcall TTerminalManager::Idle()
 {
+
+  if (FPendingConfigurationChange > 0) // optimization
+  {
+    bool Changed = false;
+
+    {
+      TGuard Guard(FChangeSection.get());
+      if (DebugAlwaysTrue(FPendingConfigurationChange > 0))
+      {
+        FPendingConfigurationChange--;
+        Changed = true;
+      }
+    }
+
+    if (Changed)
+    {
+      DoConfigurationChange();
+    }
+  }
+
   for (int Index = 0; Index < Count; Index++)
   {
     TTerminal * Terminal = Terminals[Index];

+ 4 - 0
source/windows/TerminalManager.h

@@ -93,6 +93,9 @@ private:
   TDateTime FDirectoryReadingStart;
   TAuthenticateForm * FAuthenticateForm;
   TCriticalSection * FQueueSection;
+  DWORD FMainThread;
+  int FPendingConfigurationChange;
+  std::unique_ptr<TCriticalSection> FChangeSection;
   std::vector<std::pair<TTerminalQueue *, TQueueEvent> > FQueueEvents;
   unsigned int FTaskbarButtonCreatedMessage;
   ITaskbarList3 * FTaskbarList;
@@ -162,6 +165,7 @@ private:
   void __fastcall ApplicationModalBegin(TObject * Sender);
   void __fastcall ApplicationModalEnd(TObject * Sender);
   bool __fastcall HandleMouseWheel(WPARAM WParam, LPARAM LParam);
+  void __fastcall DoConfigurationChange();
 };
 //---------------------------------------------------------------------------
 #endif