Przeglądaj źródła

Bug 1500: Poll edited file timestamps instead of using change notifications

https://winscp.net/tracker/1500

Source commit: 4059fb50a7719463fc5c826353dbb5a88b12693f
Martin Prikryl 8 lat temu
rodzic
commit
7972e0c361
2 zmienionych plików z 20 dodań i 45 usunięć
  1. 18 42
      source/windows/EditorManager.cpp
  2. 2 3
      source/windows/EditorManager.h

+ 18 - 42
source/windows/EditorManager.cpp

@@ -213,7 +213,6 @@ void __fastcall TEditorManager::AddFileInternal(const UnicodeString FileName,
   FileData.External = false;
   FileData.Process = INVALID_HANDLE_VALUE;
   FileData.Token = Token;
-  FileData.Monitor = INVALID_HANDLE_VALUE;
 
   AddFile(FileData, Data.release());
 }
@@ -228,15 +227,6 @@ void __fastcall TEditorManager::AddFileExternal(const UnicodeString FileName,
   FileData.Process = Process;
   FileData.Token = NULL;
   UnicodeString FilePath = ExtractFilePath(FileData.FileName);
-  FileData.Monitor =
-    FindFirstChangeNotification(
-      FilePath.c_str(), false, FILE_NOTIFY_CHANGE_LAST_WRITE);
-  if (FileData.Monitor == INVALID_HANDLE_VALUE)
-  {
-    throw Exception(FMTLOAD(FILE_WATCH_ERROR, (FileData.FileName)));
-  }
-
-  FMonitors.push_back(FileData.Monitor);
   if (Process != INVALID_HANDLE_VALUE)
   {
     FProcesses.push_back(Process);
@@ -248,26 +238,17 @@ void __fastcall TEditorManager::Check()
 {
   int Index;
 
-  if (FMonitors.size() > 0)
+  for (Index = 0; Index < static_cast<int>(FFiles.size()); Index++)
   {
-    do
+    TDateTime NewTimestamp;
+    if (HasFileChanged(Index, NewTimestamp))
     {
-      Index = WaitFor(FMonitors.size(), &(FMonitors[0]), MONITOR);
-
-      if (Index >= 0)
-      {
-        // let the editor finish writing to the file
-        // (first to avoid uploading partially saved file, second
-        // because the timestamp may change more than once during saving)
-        Sleep(GUIConfiguration->KeepUpToDateChangeDelay);
-
-        TFileData * FileData = &FFiles[Index];
-        FindNextChangeNotification(FileData->Monitor);
-
-        CheckFileChange(Index, false);
-      }
+      // let the editor finish writing to the file
+      // (first to avoid uploading partially saved file, second
+      // because the timestamp may change more than once during saving)
+      Sleep(GUIConfiguration->KeepUpToDateChangeDelay);
+      CheckFileChange(Index, false);
     }
-    while (Index >= 0);
   }
 
   if (FProcesses.size() > 0)
@@ -440,13 +421,6 @@ bool __fastcall TEditorManager::CloseFile(int Index, bool IgnoreErrors, bool Del
     CloseProcess(Index);
   }
 
-  if (FileData->Monitor != INVALID_HANDLE_VALUE)
-  {
-    DebugCheck(FindCloseChangeNotification(FileData->Monitor));
-    FMonitors.erase(std::find(FMonitors.begin(), FMonitors.end(), FileData->Monitor));
-    FileData->Monitor = INVALID_HANDLE_VALUE;
-  }
-
   if (FileData->UploadCompleteEvent != INVALID_HANDLE_VALUE)
   {
     FileData->Closed = true;
@@ -472,14 +446,20 @@ bool __fastcall TEditorManager::CloseFile(int Index, bool IgnoreErrors, bool Del
   return Result;
 }
 //---------------------------------------------------------------------------
-void __fastcall TEditorManager::CheckFileChange(int Index, bool Force)
+bool __fastcall TEditorManager::HasFileChanged(int Index, TDateTime & NewTimestamp)
 {
   TFileData * FileData = &FFiles[Index];
-
-  TDateTime NewTimestamp;
   FileAge(FileData->FileName, NewTimestamp);
-  if (Force || (FileData->Timestamp != NewTimestamp))
+  return (FileData->Timestamp != NewTimestamp);
+}
+//---------------------------------------------------------------------------
+void __fastcall TEditorManager::CheckFileChange(int Index, bool Force)
+{
+  TDateTime NewTimestamp;
+  bool Changed = HasFileChanged(Index, NewTimestamp);
+  if (Force || Changed)
   {
+    TFileData * FileData = &FFiles[Index];
     if (FileData->UploadCompleteEvent != INVALID_HANDLE_VALUE)
     {
       FileData->Reupload = true;
@@ -557,10 +537,6 @@ int __fastcall TEditorManager::WaitFor(unsigned int Count, const HANDLE * Handle
         HANDLE FHandle;
         switch (WaitFor)
         {
-          case MONITOR:
-            FHandle = Data->Monitor;
-            break;
-
           case PROCESS:
             FHandle = Data->Process;
             break;

+ 2 - 3
source/windows/EditorManager.h

@@ -71,7 +71,6 @@ private:
   struct TFileData
   {
     UnicodeString FileName;
-    HANDLE Monitor;
     bool External;
     HANDLE Process;
     TObject * Token;
@@ -85,7 +84,6 @@ private:
   };
 
   std::vector<TFileData> FFiles;
-  std::vector<HANDLE> FMonitors;
   std::vector<HANDLE> FProcesses;
   std::vector<HANDLE> FUploadCompleteEvents;
   TEditedFileChangedEvent FOnFileChange;
@@ -98,11 +96,12 @@ private:
   bool __fastcall CloseFile(int Index, bool IgnoreErrors, bool Delete);
   void __fastcall CloseProcess(int Index);
   bool __fastcall EarlyClose(int Index);
+  bool __fastcall HasFileChanged(int Index, TDateTime & NewTimestamp);
   void __fastcall CheckFileChange(int Index, bool Force);
   int __fastcall FindFile(const TObject * Token);
   void __fastcall ReleaseFile(int Index);
 
-  enum TWaitHandle { MONITOR, PROCESS, EVENT };
+  enum TWaitHandle { PROCESS, EVENT };
   int __fastcall WaitFor(unsigned int Count, const HANDLE * Handles,
     TWaitHandle WaitFor);
 };