From 5b43c1858d3c25c5371f83b3f6014f2b69428399 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 23 Mar 2014 00:57:03 +0000 Subject: [PATCH] Fix handling deletion of watched directory in MSW wxFileSystemWatcher. Don't log an incomprehensible error when the watched directory itself is deleted, but generate wxFSW_EVENT_DELETE for it. This is consistent with the behaviour under Unix and generally more useful. Closes #13294. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76186 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/private/fswatcher.h | 13 ++++++++++++- src/msw/fswatcher.cpp | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/include/wx/msw/private/fswatcher.h b/include/wx/msw/private/fswatcher.h index 6e1044ea1d..55c2aab927 100644 --- a/include/wx/msw/private/fswatcher.h +++ b/include/wx/msw/private/fswatcher.h @@ -225,7 +225,10 @@ public: // Special status indicating that we should exit retrieved. Status_Exit, - // Some error occurred. + // An error occurred because the watched directory was deleted. + Status_Deleted, + + // Some other error occurred. Status_Error }; @@ -248,6 +251,14 @@ public: return *count || *watch || *overlapped ? Status_OK : Status_Exit; } + // An error is returned if the underlying directory has been deleted, + // but this is not really an unexpected failure, so handle it + // specially. + if ( wxSysErrorCode() == ERROR_ACCESS_DENIED && + *watch && !wxFileName::DirExists((*watch)->GetPath()) ) + return Status_Deleted; + + // Some other error, at least log it. wxLogSysError(_("Unable to dequeue completion packet")); return Status_Error; diff --git a/src/msw/fswatcher.cpp b/src/msw/fswatcher.cpp index 98b1c1609f..cbfc0a8860 100644 --- a/src/msw/fswatcher.cpp +++ b/src/msw/fswatcher.cpp @@ -232,6 +232,21 @@ bool wxIOCPThread::ReadEvents() case wxIOCPService::Status_Error: return true; // error was logged already, we don't want to exit + case wxIOCPService::Status_Deleted: + { + wxFileSystemWatcherEvent + removeEvent(wxFSW_EVENT_DELETE, + watch->GetPath(), + wxFileName()); + SendEvent(removeEvent); + } + + // It isn't useful to continue watching this directory as it + // doesn't exist any more -- and even recreating a directory with + // the same name still wouldn't resume generating events for the + // existing wxIOCPService, so it's useless to continue. + return false; + case wxIOCPService::Status_Exit: return false; // stop reading events }