aboutsummaryrefslogtreecommitdiff
path: root/src/3rdParty/efsw/WatcherFSEvents.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdParty/efsw/WatcherFSEvents.cpp')
-rw-r--r--[-rwxr-xr-x]src/3rdParty/efsw/WatcherFSEvents.cpp80
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 @@
8namespace efsw { 8namespace efsw {
9 9
10WatcherFSEvents::WatcherFSEvents() : 10WatcherFSEvents::WatcherFSEvents() :
11 Watcher(), FWatcher( NULL ), FSStream( NULL ), WatcherGen( NULL ), initializedAsync( false ) {} 11 Watcher(), FWatcher( NULL ), FSStream( NULL ), WatcherGen( NULL ) {}
12
13WatcherFSEvents::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
21WatcherFSEvents::~WatcherFSEvents() { 13WatcherFSEvents::~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
66void 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
73void WatcherFSEvents::sendFileAction( WatchID watchid, const std::string& dir, 60void 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
80void WatcherFSEvents::handleAddModDel( const Uint32& flags, const std::string& path, 68void 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
199void WatcherFSEvents::process() { 191void 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() ) {