Browse Source

Bug 1514: Failure when reloading non-current directory expanded in remote directory tree

https://winscp.net/tracker/1514

Source commit: b8bdc023ff431bb31ac6b82cf035411a51bb2db1
Martin Prikryl 8 years ago
parent
commit
8b6a37eea6
3 changed files with 24 additions and 38 deletions
  1. 11 1
      source/components/UnixDriveView.cpp
  2. 12 35
      source/core/Terminal.cpp
  3. 1 2
      source/core/Terminal.h

+ 11 - 1
source/components/UnixDriveView.cpp

@@ -170,12 +170,20 @@ void __fastcall TCustomUnixDriveView::UpdatePath(TTreeNode * Node, bool Force,
   TNodeData * Data = NodeData(Node);
   TNodeData * Data = NodeData(Node);
   UnicodeString Path = Data->Directory;
   UnicodeString Path = Data->Directory;
 
 
-  if (FTerminal->DirectoryFileList(Path, Data->FileList, CanLoad) ||
+  TDateTime Timestamp = (Data->FileList != NULL) ? Data->FileList->Timestamp : TDateTime();
+  TRemoteFileList * FileList = FTerminal->DirectoryFileList(Path, Timestamp, CanLoad);
+  if ((FileList != NULL) ||
       ((Data->FileList != NULL) && Force))
       ((Data->FileList != NULL) && Force))
   {
   {
     TStringList * ChildrenDirs = new TStringList();
     TStringList * ChildrenDirs = new TStringList();
+    TRemoteFileList * OldFileList = NULL;
     try
     try
     {
     {
+      if (FileList != NULL)
+      {
+        OldFileList = Data->FileList;
+        Data->FileList = FileList;
+      }
       ChildrenDirs->Duplicates = Types::dupAccept;
       ChildrenDirs->Duplicates = Types::dupAccept;
       ChildrenDirs->CaseSensitive = true;
       ChildrenDirs->CaseSensitive = true;
 
 
@@ -234,6 +242,8 @@ void __fastcall TCustomUnixDriveView::UpdatePath(TTreeNode * Node, bool Force,
     __finally
     __finally
     {
     {
       delete ChildrenDirs;
       delete ChildrenDirs;
+      // Relese only files only now, once they are no longer references in the tree
+      delete OldFileList; // if not NULL
     }
     }
   }
   }
   else if (Force)
   else if (Force)

+ 12 - 35
source/core/Terminal.cpp

@@ -2300,62 +2300,39 @@ void __fastcall TTerminal::AddCachedFileList(TRemoteFileList * FileList)
   FDirectoryCache->AddFileList(FileList);
   FDirectoryCache->AddFileList(FileList);
 }
 }
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
-bool __fastcall TTerminal::DirectoryFileList(const UnicodeString Path,
-  TRemoteFileList *& FileList, bool CanLoad)
+TRemoteFileList * __fastcall TTerminal::DirectoryFileList(const UnicodeString Path, TDateTime Timestamp, bool CanLoad)
 {
 {
-  bool Result = false;
+  TRemoteFileList * Result = NULL;
   if (UnixSamePath(FFiles->Directory, Path))
   if (UnixSamePath(FFiles->Directory, Path))
   {
   {
-    Result = (FileList == NULL) || (FileList->Timestamp < FFiles->Timestamp);
-    if (Result)
+    if (Timestamp < FFiles->Timestamp)
     {
     {
-      if (FileList == NULL)
-      {
-        FileList = new TRemoteFileList();
-      }
-      FFiles->DuplicateTo(FileList);
+      Result = new TRemoteFileList();
+      FFiles->DuplicateTo(Result);
     }
     }
   }
   }
   else
   else
   {
   {
-    if (((FileList == NULL) && FDirectoryCache->HasFileList(Path)) ||
-        ((FileList != NULL) && FDirectoryCache->HasNewerFileList(Path, FileList->Timestamp)))
+    if (FDirectoryCache->HasNewerFileList(Path, Timestamp))
     {
     {
-      bool Created = (FileList == NULL);
-      if (Created)
-      {
-        FileList = new TRemoteFileList();
-      }
-
-      Result = FDirectoryCache->GetFileList(Path, FileList);
-      if (!Result && Created)
-      {
-        SAFE_DESTROY(FileList);
-      }
+      Result = new TRemoteFileList();
+      DebugAlwaysTrue(FDirectoryCache->GetFileList(Path, Result));
     }
     }
     // do not attempt to load file list if there is cached version,
     // do not attempt to load file list if there is cached version,
     // only absence of cached version indicates that we consider
     // only absence of cached version indicates that we consider
     // the directory content obsolete
     // the directory content obsolete
     else if (CanLoad && !FDirectoryCache->HasFileList(Path))
     else if (CanLoad && !FDirectoryCache->HasFileList(Path))
     {
     {
-      bool Created = (FileList == NULL);
-      if (Created)
-      {
-        FileList = new TRemoteFileList();
-      }
-      FileList->Directory = Path;
+      Result = new TRemoteFileList();
+      Result->Directory = Path;
 
 
       try
       try
       {
       {
-        ReadDirectory(FileList);
-        Result = true;
+        ReadDirectory(Result);
       }
       }
       catch(...)
       catch(...)
       {
       {
-        if (Created)
-        {
-          SAFE_DESTROY(FileList);
-        }
+        SAFE_DESTROY(Result);
         throw;
         throw;
       }
       }
     }
     }

+ 1 - 2
source/core/Terminal.h

@@ -495,8 +495,7 @@ public:
   void __fastcall SpaceAvailable(const UnicodeString Path, TSpaceAvailable & ASpaceAvailable);
   void __fastcall SpaceAvailable(const UnicodeString Path, TSpaceAvailable & ASpaceAvailable);
   void __fastcall LockFiles(TStrings * FileList);
   void __fastcall LockFiles(TStrings * FileList);
   void __fastcall UnlockFiles(TStrings * FileList);
   void __fastcall UnlockFiles(TStrings * FileList);
-  bool __fastcall DirectoryFileList(const UnicodeString Path,
-    TRemoteFileList *& FileList, bool CanLoad);
+  TRemoteFileList * __fastcall DirectoryFileList(const UnicodeString Path, TDateTime Timestamp, bool CanLoad);
   void __fastcall MakeLocalFileList(const UnicodeString FileName,
   void __fastcall MakeLocalFileList(const UnicodeString FileName,
     const TSearchRec Rec, void * Param);
     const TSearchRec Rec, void * Param);
   bool __fastcall FileOperationLoopQuery(Exception & E,
   bool __fastcall FileOperationLoopQuery(Exception & E,