Skip to content

Commit

Permalink
Added LinuxProduceSyntheticEvents option for issue #192.
Browse files Browse the repository at this point in the history
  • Loading branch information
SpartanJ committed Jan 13, 2025
1 parent 87abe59 commit ad4ac90
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 8 deletions.
11 changes: 10 additions & 1 deletion .ecode/project_build.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,16 @@
"preset": "generic",
"relative_file_paths": true
}
}
},
"run": [
{
"args": "",
"command": "efsw-test-debug",
"name": "efsw-test-debug",
"run_in_terminal": true,
"working_dir": "${project_root}/bin"
}
]
},
"linux-release": {
"build": [
Expand Down
7 changes: 7 additions & 0 deletions include/efsw/efsw.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ enum efsw_option {
/// the number of events reported. This will have an small performance and memory impact as a
/// consequence.
EFSW_OPT_MAC_SANITIZE_EVENTS = 4,
/// Linux does not support natively recursive watchers. This means that when using recursive
/// watches efsw registers new watchers for each directory. If new file are created between
/// the time efsw takes to register the new directory those events might be missed. To avoid
/// missing new file notifications efsw will trigger synthetic new file events for existing
/// files in the new directroy watched. This might have the unintended consequence of sending
/// duplicated created events due to the system also emitting this event.
LINUX_PRODUCE_SYNTHETIC_EVENTS = 5,
};

/// Basic interface for listening for file events.
Expand Down
7 changes: 7 additions & 0 deletions include/efsw/efsw.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,13 @@ enum Option {
/// the number of events reported. This will have an small performance and memory impact as a
/// consequence.
MacSanitizeEvents = 4,
/// Linux does not support natively recursive watchers. This means that when using recursive
/// watches efsw registers new watchers for each directory. If new file are created between
/// the time efsw takes to register the new directory those events might be missed. To avoid
/// missing new file notifications efsw will trigger synthetic created file events for existing
/// files in the new directroy watched. This might have the unintended consequence of sending
/// duplicated created events due to the system also emitting this event.
LinuxProduceSyntheticEvents = 5,
};
}
typedef Options::Option Option;
Expand Down
25 changes: 19 additions & 6 deletions src/efsw/FileWatcherInotify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,17 @@ FileWatcherInotify::~FileWatcherInotify() {
}

WatchID FileWatcherInotify::addWatch( const std::string& directory, FileWatchListener* watcher,
bool recursive, const std::vector<WatcherOption>& ) {
bool recursive, const std::vector<WatcherOption>& options ) {
if ( !mInitOK )
return Errors::Log::createLastError( Errors::Unspecified, directory );
Lock initLock( mInitLock );
return addWatch( directory, watcher, recursive, NULL );
bool syntheticEvents = getOptionValue( options, Options::LinuxProduceSyntheticEvents, 0 ) != 0;
return addWatch( directory, watcher, recursive, syntheticEvents, NULL );
}

WatchID FileWatcherInotify::addWatch( const std::string& directory, FileWatchListener* watcher,
bool recursive, WatcherInotify* parent ) {
bool recursive, bool syntheticEvents,
WatcherInotify* parent, bool fromInternalEvent ) {
std::string dir( directory );

FileSystem::dirAddSlashAtEnd( dir );
Expand Down Expand Up @@ -160,7 +162,17 @@ WatchID FileWatcherInotify::addWatch( const std::string& directory, FileWatchLis
const FileInfo& cfi = it->second;

if ( cfi.isDirectory() && cfi.isReadable() ) {
addWatch( cfi.Filepath, watcher, recursive, pWatch );
addWatch( cfi.Filepath, watcher, recursive, syntheticEvents, pWatch );
}
}

if ( fromInternalEvent && parent != NULL && syntheticEvents ) {
for ( const auto& file : files ) {
if ( file.second.isRegularFile() ) {
pWatch->Listener->handleFileAction(
pWatch->ID, pWatch->Directory,
FileSystem::fileNameFromPath( file.second.Filepath ), Actions::Add );
}
}
}
}
Expand Down Expand Up @@ -448,8 +460,9 @@ void FileWatcherInotify::checkForNewWatcher( Watcher* watch, std::string fpath )
}

if ( !found ) {
addWatch( fpath, watch->Listener, watch->Recursive,
static_cast<WatcherInotify*>( watch ) );
WatcherInotify* iWatch = static_cast<WatcherInotify*>( watch );
addWatch( fpath, watch->Listener, watch->Recursive, iWatch->syntheticEvents,
static_cast<WatcherInotify*>( watch ), true );
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/efsw/FileWatcherInotify.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ class FileWatcherInotify : public FileWatcherImpl {
std::vector<std::pair<WatcherInotify*, std::string>> mMovedOutsideWatches;

WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive,
WatcherInotify* parent = NULL );
bool syntheticEvents, WatcherInotify* parent = NULL,
bool fromInternalEvent = false );

bool pathInWatches( const std::string& path ) override;

Expand Down
1 change: 1 addition & 0 deletions src/efsw/WatcherInotify.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class WatcherInotify : public Watcher {
WatchID InotifyID;

FileInfo DirInfo;
bool syntheticEvents{ false };
};

} // namespace efsw
Expand Down

0 comments on commit ad4ac90

Please sign in to comment.