aboutsummaryrefslogtreecommitdiff
path: root/dep/efsw/src/efsw/FileWatcherInotify.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dep/efsw/src/efsw/FileWatcherInotify.cpp')
-rw-r--r--dep/efsw/src/efsw/FileWatcherInotify.cpp97
1 files changed, 74 insertions, 23 deletions
diff --git a/dep/efsw/src/efsw/FileWatcherInotify.cpp b/dep/efsw/src/efsw/FileWatcherInotify.cpp
index 29be12b6262..cb751ba88ee 100644
--- a/dep/efsw/src/efsw/FileWatcherInotify.cpp
+++ b/dep/efsw/src/efsw/FileWatcherInotify.cpp
@@ -7,6 +7,7 @@
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
+#include <sys/select.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -69,15 +70,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 );
@@ -137,6 +140,7 @@ WatchID FileWatcherInotify::addWatch( const std::string& directory, FileWatchLis
pWatch->Directory = dir;
pWatch->Recursive = recursive;
pWatch->Parent = parent;
+ pWatch->syntheticEvents = syntheticEvents;
{
Lock lock( mWatchesLock );
@@ -151,6 +155,18 @@ WatchID FileWatcherInotify::addWatch( const std::string& directory, FileWatchLis
if ( pWatch->Recursive ) {
std::map<std::string, FileInfo> files = FileSystem::filesInfoFromPath( pWatch->Directory );
+
+ if ( fromInternalEvent && parent != NULL && syntheticEvents ) {
+ for ( const auto& file : files ) {
+ if ( file.second.isRegularFile() || file.second.isDirectory() ||
+ file.second.isLink() ) {
+ pWatch->Listener->handleFileAction(
+ pWatch->ID, pWatch->Directory,
+ FileSystem::fileNameFromPath( file.second.Filepath ), Actions::Add );
+ }
+ }
+ }
+
std::map<std::string, FileInfo>::iterator it = files.begin();
for ( ; it != files.end(); ++it ) {
@@ -160,7 +176,8 @@ 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,
+ fromInternalEvent );
}
}
}
@@ -244,7 +261,7 @@ void FileWatcherInotify::removeWatch( WatchID watchid ) {
void FileWatcherInotify::watch() {
if ( NULL == mThread ) {
- mThread = new Thread( &FileWatcherInotify::run, this );
+ mThread = new Thread( [this] { run(); } );
mThread->launch();
}
}
@@ -267,10 +284,10 @@ Watcher* FileWatcherInotify::watcherContainsDirectory( std::string dir ) {
void FileWatcherInotify::run() {
char* buff = new char[BUFF_SIZE];
memset( buff, 0, BUFF_SIZE );
- WatchMap::iterator wit;
+ WatcherInotify* curWatcher = NULL;
WatcherInotify* currentMoveFrom = NULL;
- u_int32_t currentMoveCookie = -1;
+ uint32_t currentMoveCookie = -1;
bool lastWasMovedFrom = false;
std::string prevOldFileName;
@@ -294,16 +311,21 @@ void FileWatcherInotify::run() {
struct inotify_event* pevent = (struct inotify_event*)&buff[i];
{
+ curWatcher = NULL;
+
{
Lock lock( mWatchesLock );
- wit = mWatches.find( pevent->wd );
+ auto wit = mWatches.find( pevent->wd );
+
+ if ( wit != mWatches.end() )
+ curWatcher = wit->second;
}
- if ( wit != mWatches.end() ) {
- handleAction( wit->second, (char*)pevent->name, pevent->mask );
+ if ( curWatcher ) {
+ handleAction( curWatcher, (char*)pevent->name, pevent->mask );
- if ( ( pevent->mask & IN_MOVED_TO ) && wit->second == currentMoveFrom &&
+ if ( ( pevent->mask & IN_MOVED_TO ) && curWatcher == currentMoveFrom &&
pevent->cookie == currentMoveCookie ) {
/// make pair success
currentMoveFrom = NULL;
@@ -316,14 +338,30 @@ void FileWatcherInotify::run() {
std::make_pair( currentMoveFrom, prevOldFileName ) );
}
- currentMoveFrom = wit->second;
+ currentMoveFrom = curWatcher;
currentMoveCookie = pevent->cookie;
} else {
/// Keep track of the IN_MOVED_FROM events to know
/// if the IN_MOVED_TO event is also fired
if ( currentMoveFrom ) {
- mMovedOutsideWatches.push_back(
- std::make_pair( currentMoveFrom, prevOldFileName ) );
+ if ( std::find_if( mMovedOutsideWatches.begin(),
+ mMovedOutsideWatches.end(),
+ [currentMoveFrom](
+ const std::pair<WatcherInotify*,
+ std::string>& moved ) {
+ return moved.first == currentMoveFrom;
+ } ) == mMovedOutsideWatches.end() ) {
+ mMovedOutsideWatches.push_back(
+ std::make_pair( currentMoveFrom, prevOldFileName ) );
+ } else {
+ efDEBUG( "Info: Tried to add watch to the moved outside "
+ "watches but it was already there, Watch ID: %d - "
+ "Address: %p - Path: \"%s\" - prevOldFileName: "
+ "\"%s\"\n",
+ pevent->wd, currentMoveFrom,
+ currentMoveFrom->Directory.c_str(),
+ prevOldFileName.c_str() );
+ }
}
currentMoveFrom = NULL;
@@ -343,8 +381,18 @@ void FileWatcherInotify::run() {
// Here means no event received
// If last event is IN_MOVED_FROM, we assume no IN_MOVED_TO
if ( currentMoveFrom ) {
- mMovedOutsideWatches.push_back(
- std::make_pair( currentMoveFrom, currentMoveFrom->OldFileName ) );
+ if ( std::find_if(
+ mMovedOutsideWatches.begin(), mMovedOutsideWatches.end(),
+ [currentMoveFrom]( const std::pair<WatcherInotify*, std::string>& moved ) {
+ return moved.first == currentMoveFrom;
+ } ) == mMovedOutsideWatches.end() ) {
+ mMovedOutsideWatches.push_back(
+ std::make_pair( currentMoveFrom, currentMoveFrom->OldFileName ) );
+ } else {
+ efDEBUG( "Warning: Tried to add watch to the moved outside "
+ "watches but it was already there, Watch Address: %p\n",
+ currentMoveFrom );
+ }
}
currentMoveFrom = NULL;
@@ -378,8 +426,8 @@ void FileWatcherInotify::run() {
continue;
}
- Watcher* watch = ( *it ).first;
- const std::string& oldFileName = ( *it ).second;
+ Watcher* watch = it->first;
+ const std::string& oldFileName = it->second;
/// Check if the file move was a folder already being watched
std::vector<Watcher*> eraseWatches;
@@ -387,8 +435,8 @@ void FileWatcherInotify::run() {
{
Lock lock( mWatchesLock );
- for ( ; wit != mWatches.end(); ++wit ) {
- Watcher* oldWatch = wit->second;
+ for ( auto wit : mWatches ) {
+ Watcher* oldWatch = wit.second;
if ( oldWatch != watch &&
-1 != String::strStartsWith( watch->Directory + oldFileName + "/",
@@ -448,8 +496,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 );
}
}
}
@@ -464,7 +513,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 ) {