diff options
| author | Li Jin <dragon-fly@qq.com> | 2025-04-09 17:40:13 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2025-04-09 17:40:13 +0800 |
| commit | 9750786a5c03b5ce3ea22b240d1b3cd34990856b (patch) | |
| tree | e495e43245e1bacc86d33142af202613a82a40c1 /src/3rdParty/efsw/WatcherFSEvents.cpp | |
| parent | 571fb952b99e580a0381f539885f8f175e2ec3b0 (diff) | |
| download | yuescript-9750786a5c03b5ce3ea22b240d1b3cd34990856b.tar.gz yuescript-9750786a5c03b5ce3ea22b240d1b3cd34990856b.tar.bz2 yuescript-9750786a5c03b5ce3ea22b240d1b3cd34990856b.zip | |
Updated efsw. Fixed issue #204.
Diffstat (limited to 'src/3rdParty/efsw/WatcherFSEvents.cpp')
| -rw-r--r--[-rwxr-xr-x] | src/3rdParty/efsw/WatcherFSEvents.cpp | 80 |
1 files changed, 36 insertions, 44 deletions
diff --git a/src/3rdParty/efsw/WatcherFSEvents.cpp b/src/3rdParty/efsw/WatcherFSEvents.cpp index b562d3c..f963374 100755..100644 --- a/src/3rdParty/efsw/WatcherFSEvents.cpp +++ b/src/3rdParty/efsw/WatcherFSEvents.cpp | |||
| @@ -8,22 +8,11 @@ | |||
| 8 | namespace efsw { | 8 | namespace efsw { |
| 9 | 9 | ||
| 10 | WatcherFSEvents::WatcherFSEvents() : | 10 | WatcherFSEvents::WatcherFSEvents() : |
| 11 | Watcher(), FWatcher( NULL ), FSStream( NULL ), WatcherGen( NULL ), initializedAsync( false ) {} | 11 | Watcher(), FWatcher( NULL ), FSStream( NULL ), WatcherGen( NULL ) {} |
| 12 | |||
| 13 | WatcherFSEvents::WatcherFSEvents( WatchID id, std::string directory, FileWatchListener* listener, | ||
| 14 | bool recursive, WatcherFSEvents* /*parent*/ ) : | ||
| 15 | Watcher( id, directory, listener, recursive ), | ||
| 16 | FWatcher( NULL ), | ||
| 17 | FSStream( NULL ), | ||
| 18 | WatcherGen( NULL ), | ||
| 19 | initializedAsync( false ) {} | ||
| 20 | 12 | ||
| 21 | WatcherFSEvents::~WatcherFSEvents() { | 13 | WatcherFSEvents::~WatcherFSEvents() { |
| 22 | if ( NULL != FSStream ) { | 14 | if ( NULL != FSStream ) { |
| 23 | if ( initializedAsync ) { | 15 | FSEventStreamStop( FSStream ); |
| 24 | FSEventStreamStop( FSStream ); | ||
| 25 | } | ||
| 26 | |||
| 27 | FSEventStreamInvalidate( FSStream ); | 16 | FSEventStreamInvalidate( FSStream ); |
| 28 | FSEventStreamRelease( FSStream ); | 17 | FSEventStreamRelease( FSStream ); |
| 29 | } | 18 | } |
| @@ -39,7 +28,9 @@ void WatcherFSEvents::init() { | |||
| 39 | Uint32 streamFlags = kFSEventStreamCreateFlagNone; | 28 | Uint32 streamFlags = kFSEventStreamCreateFlagNone; |
| 40 | 29 | ||
| 41 | if ( FileWatcherFSEvents::isGranular() ) { | 30 | if ( FileWatcherFSEvents::isGranular() ) { |
| 42 | streamFlags = efswFSEventStreamCreateFlagFileEvents; | 31 | streamFlags = efswFSEventStreamCreateFlagFileEvents | efswFSEventStreamCreateFlagNoDefer | |
| 32 | efswFSEventStreamCreateFlagUseExtendedData | | ||
| 33 | efswFSEventStreamCreateFlagUseCFTypes; | ||
| 43 | } else { | 34 | } else { |
| 44 | WatcherGen = new WatcherGeneric( ID, Directory, Listener, FWatcher.load(), Recursive ); | 35 | WatcherGen = new WatcherGeneric( ID, Directory, Listener, FWatcher.load(), Recursive ); |
| 45 | } | 36 | } |
| @@ -52,49 +43,49 @@ void WatcherFSEvents::init() { | |||
| 52 | ctx.release = NULL; | 43 | ctx.release = NULL; |
| 53 | ctx.copyDescription = NULL; | 44 | ctx.copyDescription = NULL; |
| 54 | 45 | ||
| 46 | dispatch_queue_t queue = dispatch_queue_create( NULL, NULL ); | ||
| 47 | |||
| 55 | FSStream = | 48 | FSStream = |
| 56 | FSEventStreamCreate( kCFAllocatorDefault, &FileWatcherFSEvents::FSEventCallback, &ctx, | 49 | FSEventStreamCreate( kCFAllocatorDefault, &FileWatcherFSEvents::FSEventCallback, &ctx, |
| 57 | CFDirectoryArray, kFSEventStreamEventIdSinceNow, 0.25, streamFlags ); | 50 | CFDirectoryArray, kFSEventStreamEventIdSinceNow, 0., streamFlags ); |
| 58 | FWatcher.load()->mNeedInitMutex.lock(); | ||
| 59 | FWatcher.load()->mNeedInit.push_back( this ); | ||
| 60 | FWatcher.load()->mNeedInitMutex.unlock(); | ||
| 61 | 51 | ||
| 62 | CFRelease( CFDirectoryArray ); | 52 | FSEventStreamSetDispatchQueue( FSStream, queue ); |
| 63 | CFRelease( CFDirectory ); | ||
| 64 | } | ||
| 65 | 53 | ||
| 66 | void WatcherFSEvents::initAsync() { | ||
| 67 | FSEventStreamScheduleWithRunLoop( FSStream, FWatcher.load()->mRunLoopRef.load(), | ||
| 68 | kCFRunLoopDefaultMode ); | ||
| 69 | FSEventStreamStart( FSStream ); | 54 | FSEventStreamStart( FSStream ); |
| 70 | initializedAsync = true; | 55 | |
| 56 | CFRelease( CFDirectoryArray ); | ||
| 57 | CFRelease( CFDirectory ); | ||
| 71 | } | 58 | } |
| 72 | 59 | ||
| 73 | void WatcherFSEvents::sendFileAction( WatchID watchid, const std::string& dir, | 60 | void WatcherFSEvents::sendFileAction( WatchID watchid, const std::string& dir, |
| 74 | const std::string& filename, Action action, | 61 | const std::string& filename, Action action, |
| 75 | std::string oldFilename ) { | 62 | std::string oldFilename ) { |
| 76 | Listener->handleFileAction( watchid, FileSystem::precomposeFileName( dir ), | 63 | Listener->handleFileAction( watchid, FileSystem::precomposeFileName( dir ), |
| 77 | FileSystem::precomposeFileName( filename ), action, oldFilename ); | 64 | FileSystem::precomposeFileName( filename ), action, |
| 65 | FileSystem::precomposeFileName( oldFilename ) ); | ||
| 78 | } | 66 | } |
| 79 | 67 | ||
| 80 | void WatcherFSEvents::handleAddModDel( const Uint32& flags, const std::string& path, | 68 | void WatcherFSEvents::handleAddModDel( const Uint32& flags, const std::string& path, |
| 81 | std::string& dirPath, std::string& filePath ) { | 69 | std::string& dirPath, std::string& filePath, Uint64 inode ) { |
| 82 | if ( flags & efswFSEventStreamEventFlagItemCreated ) { | 70 | if ( ( flags & efswFSEventStreamEventFlagItemCreated ) && FileInfo::exists( path ) && |
| 83 | if ( FileInfo::exists( path ) ) { | 71 | ( !SanitizeEvents || FilesAdded.find( inode ) != FilesAdded.end() ) ) { |
| 84 | sendFileAction( ID, dirPath, filePath, Actions::Add ); | 72 | sendFileAction( ID, dirPath, filePath, Actions::Add ); |
| 85 | } | 73 | |
| 74 | if ( SanitizeEvents ) | ||
| 75 | FilesAdded.insert( inode ); | ||
| 86 | } | 76 | } |
| 87 | 77 | ||
| 88 | if ( flags & efswFSEventsModified ) { | 78 | if ( flags & ModifiedFlags ) { |
| 89 | sendFileAction( ID, dirPath, filePath, Actions::Modified ); | 79 | sendFileAction( ID, dirPath, filePath, Actions::Modified ); |
| 90 | } | 80 | } |
| 91 | 81 | ||
| 92 | if ( flags & efswFSEventStreamEventFlagItemRemoved ) { | 82 | if ( ( flags & efswFSEventStreamEventFlagItemRemoved ) && !FileInfo::exists( path ) ) { |
| 93 | // Since i don't know the order, at least i try to keep the data consistent with the real | 83 | // Since i don't know the order, at least i try to keep the data consistent with the real |
| 94 | // state | 84 | // state |
| 95 | if ( !FileInfo::exists( path ) ) { | 85 | sendFileAction( ID, dirPath, filePath, Actions::Delete ); |
| 96 | sendFileAction( ID, dirPath, filePath, Actions::Delete ); | 86 | |
| 97 | } | 87 | if ( SanitizeEvents ) |
| 88 | FilesAdded.erase( inode ); | ||
| 98 | } | 89 | } |
| 99 | } | 90 | } |
| 100 | 91 | ||
| @@ -136,19 +127,20 @@ void WatcherFSEvents::handleActions( std::vector<FSEvent>& events ) { | |||
| 136 | // been added modified and erased, but i can't know if first was erased and then added | 127 | // been added modified and erased, but i can't know if first was erased and then added |
| 137 | // and modified, or added, then modified and then erased. I don't know what they were | 128 | // and modified, or added, then modified and then erased. I don't know what they were |
| 138 | // thinking by doing this... | 129 | // thinking by doing this... |
| 139 | efDEBUG( "Event in: %s - flags: %ld\n", event.Path.c_str(), event.Flags ); | 130 | efDEBUG( "Event in: %s - flags: 0x%x\n", event.Path.c_str(), event.Flags ); |
| 140 | 131 | ||
| 141 | if ( event.Flags & efswFSEventStreamEventFlagItemRenamed ) { | 132 | if ( event.Flags & efswFSEventStreamEventFlagItemRenamed ) { |
| 142 | if ( ( i + 1 < esize ) && | 133 | if ( ( i + 1 < esize ) && |
| 143 | ( events[i + 1].Flags & efswFSEventStreamEventFlagItemRenamed ) && | 134 | ( events[i + 1].Flags & efswFSEventStreamEventFlagItemRenamed ) && |
| 144 | ( events[i + 1].Id == event.Id + 1 ) ) { | 135 | ( events[i + 1].inode == event.inode ) ) { |
| 145 | FSEvent& nEvent = events[i + 1]; | 136 | FSEvent& nEvent = events[i + 1]; |
| 146 | std::string newDir( FileSystem::pathRemoveFileName( nEvent.Path ) ); | 137 | std::string newDir( FileSystem::pathRemoveFileName( nEvent.Path ) ); |
| 147 | std::string newFilepath( FileSystem::fileNameFromPath( nEvent.Path ) ); | 138 | std::string newFilepath( FileSystem::fileNameFromPath( nEvent.Path ) ); |
| 148 | 139 | ||
| 149 | if ( event.Path != nEvent.Path ) { | 140 | if ( event.Path != nEvent.Path ) { |
| 150 | if ( dirPath == newDir ) { | 141 | if ( dirPath == newDir ) { |
| 151 | if ( !FileInfo::exists( event.Path ) ) { | 142 | if ( !FileInfo::exists( event.Path ) || |
| 143 | 0 == strcasecmp( event.Path.c_str(), nEvent.Path.c_str() ) ) { | ||
| 152 | sendFileAction( ID, dirPath, newFilepath, Actions::Moved, | 144 | sendFileAction( ID, dirPath, newFilepath, Actions::Moved, |
| 153 | filePath ); | 145 | filePath ); |
| 154 | } else { | 146 | } else { |
| @@ -159,12 +151,12 @@ void WatcherFSEvents::handleActions( std::vector<FSEvent>& events ) { | |||
| 159 | sendFileAction( ID, dirPath, filePath, Actions::Delete ); | 151 | sendFileAction( ID, dirPath, filePath, Actions::Delete ); |
| 160 | sendFileAction( ID, newDir, newFilepath, Actions::Add ); | 152 | sendFileAction( ID, newDir, newFilepath, Actions::Add ); |
| 161 | 153 | ||
| 162 | if ( nEvent.Flags & efswFSEventsModified ) { | 154 | if ( nEvent.Flags & ModifiedFlags ) { |
| 163 | sendFileAction( ID, newDir, newFilepath, Actions::Modified ); | 155 | sendFileAction( ID, newDir, newFilepath, Actions::Modified ); |
| 164 | } | 156 | } |
| 165 | } | 157 | } |
| 166 | } else { | 158 | } else { |
| 167 | handleAddModDel( nEvent.Flags, nEvent.Path, dirPath, filePath ); | 159 | handleAddModDel( nEvent.Flags, nEvent.Path, dirPath, filePath, event.inode ); |
| 168 | } | 160 | } |
| 169 | 161 | ||
| 170 | if ( nEvent.Flags & ( efswFSEventStreamEventFlagItemCreated | | 162 | if ( nEvent.Flags & ( efswFSEventStreamEventFlagItemCreated | |
| @@ -180,14 +172,14 @@ void WatcherFSEvents::handleActions( std::vector<FSEvent>& events ) { | |||
| 180 | } else if ( FileInfo::exists( event.Path ) ) { | 172 | } else if ( FileInfo::exists( event.Path ) ) { |
| 181 | sendFileAction( ID, dirPath, filePath, Actions::Add ); | 173 | sendFileAction( ID, dirPath, filePath, Actions::Add ); |
| 182 | 174 | ||
| 183 | if ( event.Flags & efswFSEventsModified ) { | 175 | if ( event.Flags & ModifiedFlags ) { |
| 184 | sendFileAction( ID, dirPath, filePath, Actions::Modified ); | 176 | sendFileAction( ID, dirPath, filePath, Actions::Modified ); |
| 185 | } | 177 | } |
| 186 | } else { | 178 | } else { |
| 187 | sendFileAction( ID, dirPath, filePath, Actions::Delete ); | 179 | sendFileAction( ID, dirPath, filePath, Actions::Delete ); |
| 188 | } | 180 | } |
| 189 | } else { | 181 | } else { |
| 190 | handleAddModDel( event.Flags, event.Path, dirPath, filePath ); | 182 | handleAddModDel( event.Flags, event.Path, dirPath, filePath, event.inode ); |
| 191 | } | 183 | } |
| 192 | } else { | 184 | } else { |
| 193 | efDEBUG( "Directory: %s changed\n", event.Path.c_str() ); | 185 | efDEBUG( "Directory: %s changed\n", event.Path.c_str() ); |
| @@ -197,7 +189,7 @@ void WatcherFSEvents::handleActions( std::vector<FSEvent>& events ) { | |||
| 197 | } | 189 | } |
| 198 | 190 | ||
| 199 | void WatcherFSEvents::process() { | 191 | void WatcherFSEvents::process() { |
| 200 | std::set<std::string>::iterator it = DirsChanged.begin(); | 192 | std::unordered_set<std::string>::iterator it = DirsChanged.begin(); |
| 201 | 193 | ||
| 202 | for ( ; it != DirsChanged.end(); it++ ) { | 194 | for ( ; it != DirsChanged.end(); it++ ) { |
| 203 | if ( !FileWatcherFSEvents::isGranular() ) { | 195 | if ( !FileWatcherFSEvents::isGranular() ) { |
