diff --git a/include/efsw/efsw.hpp b/include/efsw/efsw.hpp index 11a5dec..8c2759b 100644 --- a/include/efsw/efsw.hpp +++ b/include/efsw/efsw.hpp @@ -245,6 +245,12 @@ class FileWatchListener { virtual void handleFileAction( WatchID watchid, const std::string& dir, const std::string& filename, Action action, std::string oldFilename = "" ) = 0; + + /// Handles that have missed file actions + /// @param watchid The watch id for the directory + /// @param dir The directory + virtual void handleMissedFileActions( WatchID /*watchid*/, + const std::string& /*dir*/ ) {}; }; /// Optional, typically platform specific parameter for customization of a watcher. diff --git a/src/efsw/FileWatcherInotify.cpp b/src/efsw/FileWatcherInotify.cpp index 68107e9..409ac04 100644 --- a/src/efsw/FileWatcherInotify.cpp +++ b/src/efsw/FileWatcherInotify.cpp @@ -512,7 +512,9 @@ void FileWatcherInotify::handleAction( Watcher* watch, const std::string& filena std::string fpath( watch->Directory + filename ); - if ( ( IN_CLOSE_WRITE & action ) || ( IN_MODIFY & action ) ) { + if ( IN_Q_OVERFLOW & action ) { + watch->Listener->handleMissedFileActions( watch->ID, watch->Directory ); + } else if ( ( IN_CLOSE_WRITE & action ) || ( IN_MODIFY & action ) ) { watch->Listener->handleFileAction( watch->ID, watch->Directory, filename, Actions::Modified ); } else if ( IN_MOVED_TO & action ) { diff --git a/src/efsw/WatcherFSEvents.cpp b/src/efsw/WatcherFSEvents.cpp index f963374..bc982bf 100644 --- a/src/efsw/WatcherFSEvents.cpp +++ b/src/efsw/WatcherFSEvents.cpp @@ -65,6 +65,12 @@ void WatcherFSEvents::sendFileAction( WatchID watchid, const std::string& dir, FileSystem::precomposeFileName( oldFilename ) ); } +void WatcherFSEvents::sendMissedFileActions( WatchID watchid, + const std::string& dir) { + Listener->handleMissedFileActions( watchid, + FileSystem::precomposeFileName( dir ) ); +} + void WatcherFSEvents::handleAddModDel( const Uint32& flags, const std::string& path, std::string& dirPath, std::string& filePath, Uint64 inode ) { if ( ( flags & efswFSEventStreamEventFlagItemCreated ) && FileInfo::exists( path ) && @@ -97,7 +103,16 @@ void WatcherFSEvents::handleActions( std::vector& events ) { if ( event.Flags & ( kFSEventStreamEventFlagUserDropped | kFSEventStreamEventFlagKernelDropped | - kFSEventStreamEventFlagEventIdsWrapped | kFSEventStreamEventFlagHistoryDone | + kFSEventStreamEventFlagMustScanSubDirs) ) { + efDEBUG( "Rescan/Drop event for watch: %s - flags: 0x%x\n", Directory.c_str(), event.Flags ); + std::string dirPath = Directory; + FileSystem::dirRemoveSlashAtEnd( dirPath ); + sendMissedFileActions(ID, dirPath ); + continue; + } + + if ( event.Flags & + ( kFSEventStreamEventFlagEventIdsWrapped | kFSEventStreamEventFlagHistoryDone | kFSEventStreamEventFlagMount | kFSEventStreamEventFlagUnmount | kFSEventStreamEventFlagRootChanged ) ) { continue; diff --git a/src/efsw/WatcherFSEvents.hpp b/src/efsw/WatcherFSEvents.hpp index f05b094..fe17ed4 100644 --- a/src/efsw/WatcherFSEvents.hpp +++ b/src/efsw/WatcherFSEvents.hpp @@ -78,6 +78,8 @@ class WatcherFSEvents : public Watcher { void sendFileAction( WatchID watchid, const std::string& dir, const std::string& filename, Action action, std::string oldFilename = "" ); + + void sendMissedFileActions( WatchID watchid, const std::string& dir); }; } // namespace efsw diff --git a/src/efsw/WatcherWin32.cpp b/src/efsw/WatcherWin32.cpp index 712419e..d8d47aa 100644 --- a/src/efsw/WatcherWin32.cpp +++ b/src/efsw/WatcherWin32.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -162,6 +163,10 @@ void CALLBACK WatchCallback( DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOve if ( dwNumberOfBytesTransfered == 0 ) { if ( nullptr != pWatch && !pWatch->StopNow ) { + /// Missed file actions due to buffer overflowed + std::string dir = pWatch->DirName; + FileSystem::dirRemoveSlashAtEnd( dir ); + pWatch->Listener->handleMissedFileActions( pWatch->ID, dir ); RefreshWatch( tWatch ); } else { return;