33#include < CoreServices/CoreServices.h>
44
55#include < iostream>
6- #include < thread>
76
87std::string eventFlagsToString (FSEventStreamEventFlags eventFlags)
98{
9+ std::cout << " FSEventStreamEventFlags: " << std::to_string (eventFlags) << std::endl;
10+
11+ std::string text;
1012 if ((eventFlags & kFSEventStreamEventFlagNone ) != 0U ) {
11- return " None: " ;
13+ text += " None" ;
1214 }
1315 if ((eventFlags & kFSEventStreamEventFlagMustScanSubDirs ) != 0U ) {
14- return " MustScanSubDirs: " ;
16+ text += " MustScanSubDirs " ;
1517 }
1618 if ((eventFlags & kFSEventStreamEventFlagUserDropped ) != 0U ) {
17- return " UserDropped: " ;
19+ text += " UserDropped " ;
1820 }
1921 if ((eventFlags & kFSEventStreamEventFlagKernelDropped ) != 0U ) {
20- return " KernelDropped: " ;
22+ text += " KernelDropped " ;
2123 }
2224 if ((eventFlags & kFSEventStreamEventFlagEventIdsWrapped ) != 0U ) {
23- return " EventIdsWrapped: " ;
25+ text += " EventIdsWrapped " ;
2426 }
2527 if ((eventFlags & kFSEventStreamEventFlagHistoryDone ) != 0U ) {
26- return " HistoryDone: " ;
28+ text += " HistoryDone " ;
2729 }
2830 if ((eventFlags & kFSEventStreamEventFlagRootChanged ) != 0U ) {
29- return " RootChanged: " ;
31+ text += " RootChanged " ;
3032 }
3133 if ((eventFlags & kFSEventStreamEventFlagMount ) != 0U ) {
32- return " Mount: " ;
34+ text += " Mount " ;
3335 }
3436 if ((eventFlags & kFSEventStreamEventFlagUnmount ) != 0U ) {
35- return " Unmount: " ;
37+ text += " Unmount " ;
3638 }
3739 if ((eventFlags & kFSEventStreamEventFlagItemCreated ) != 0U ) {
38- return " Created: " ;
40+ text += " Created " ;
3941 }
4042 if ((eventFlags & kFSEventStreamEventFlagItemRemoved ) != 0U ) {
41- return " Removed: " ;
43+ text += " Removed " ;
4244 }
4345 if ((eventFlags & kFSEventStreamEventFlagItemInodeMetaMod ) != 0U ) {
44- return " InodeMetaMod: " ;
46+ text += " InodeMetaMod " ;
4547 }
4648 if ((eventFlags & kFSEventStreamEventFlagItemRenamed ) != 0U ) {
47- return " Renamed: " ;
49+ text += " Renamed " ;
4850 }
4951 if ((eventFlags & kFSEventStreamEventFlagItemModified ) != 0U ) {
50- return " Modified: " ;
52+ text += " Modified " ;
5153 }
5254 if ((eventFlags & kFSEventStreamEventFlagItemFinderInfoMod ) != 0U ) {
53- return " FinderInfoMod: " ;
55+ text += " FinderInfoMod " ;
5456 }
5557 if ((eventFlags & kFSEventStreamEventFlagItemChangeOwner ) != 0U ) {
56- return " ChangeOwner: " ;
58+ text += " ChangeOwner " ;
5759 }
5860 if ((eventFlags & kFSEventStreamEventFlagItemXattrMod ) != 0U ) {
59- return " XattrMod: " ;
61+ text += " XattrMod " ;
6062 }
6163 if ((eventFlags & kFSEventStreamEventFlagItemIsFile ) != 0U ) {
62- return " IsFile: " ;
64+ text += " IsFile " ;
6365 }
6466 if ((eventFlags & kFSEventStreamEventFlagItemIsDir ) != 0U ) {
65- return " IsDir: " ;
67+ text += " IsDir " ;
6668 }
6769 if ((eventFlags & kFSEventStreamEventFlagItemIsSymlink ) != 0U ) {
68- return " IsSymlink: " ;
70+ text += " IsSymlink " ;
6971 }
7072 if ((eventFlags & kFSEventStreamEventFlagOwnEvent ) != 0U ) {
71- return " OwnEvent: " ;
73+ text += " OwnEvent " ;
7274 }
7375 if ((eventFlags & kFSEventStreamEventFlagItemIsHardlink ) != 0U ) {
74- return " IsHardlink: " ;
76+ text += " IsHardlink " ;
7577 }
7678 if ((eventFlags & kFSEventStreamEventFlagItemIsLastHardlink ) != 0U ) {
77- return " IsLastHardlink: " ;
79+ text += " IsLastHardlink " ;
7880 }
7981 if ((eventFlags & kFSEventStreamEventFlagItemCloned ) != 0U ) {
80- return " Cloned: " ;
82+ text += " Cloned " ;
83+ }
84+ if (text.empty ()) {
85+ text = " Unknown " + std::to_string (eventFlags) + " " ;
86+ } else {
87+ text += " : " ;
8188 }
82- return " Unknown " + std::to_string (eventFlags) + " : " ;
89+ return text ;
8390}
8491
8592class MonitorDir ::MonitorDirPrivate
@@ -101,7 +108,7 @@ class MonitorDir::MonitorDirPrivate
101108 // auto *monitorDir = static_cast<MonitorDirPrivate *>(clientCallBackInfo);
102109 char **paths = static_cast <char **>(eventPaths);
103110 if (paths == nullptr ) {
104- std::cerr << " Error: paths is null." << std::endl;
111+ std::cerr << " Errorpaths is null." << std::endl;
105112 return ;
106113 }
107114 for (size_t i = 0 ; i < numEvents; ++i) {
@@ -113,54 +120,55 @@ class MonitorDir::MonitorDirPrivate
113120 }
114121 }
115122
116- void monitor ()
123+ bool monitor ()
117124 {
118- std::cout << " addWatch: " << dir << std::endl;
119- CFStringRef pathToWatch = CFStringCreateWithCString (kCFAllocatorDefault ,
120- dir.c_str (),
121- kCFStringEncodingUTF8 );
122- CFArrayRef pathsToWatch = CFArrayCreate (kCFAllocatorDefault ,
123- reinterpret_cast <const void **>(&pathToWatch),
124- 1 ,
125- nullptr );
125+ std::cout << " addWatch" << dir << std::endl;
126+ auto pathToWatch = CFStringCreateWithCString (kCFAllocatorDefault ,
127+ dir.c_str (),
128+ kCFStringEncodingUTF8 );
129+ auto pathsToWatch = CFArrayCreate (kCFAllocatorDefault ,
130+ reinterpret_cast <const void **>(&pathToWatch),
131+ 1 ,
132+ nullptr );
126133 FSEventStreamContext context{0 , this , nullptr , nullptr , nullptr };
127- FSEventStreamRef stream = FSEventStreamCreate (kCFAllocatorDefault ,
128- monitorCallback,
129- &context,
130- pathsToWatch,
131- kFSEventStreamEventIdSinceNow ,
132- 3 ,
133- kFSEventStreamCreateFlagFileEvents );
134- runLoop = CFRunLoopGetCurrent ();
135- FSEventStreamScheduleWithRunLoop (stream, runLoop, kCFRunLoopDefaultMode );
134+ stream = FSEventStreamCreate (kCFAllocatorDefault ,
135+ monitorCallback,
136+ &context,
137+ pathsToWatch,
138+ kFSEventStreamEventIdSinceNow ,
139+ 0 .,
140+ kFSEventStreamCreateFlagFileEvents );
141+ if (stream == nullptr ) {
142+ std::cerr << " Failed to create FSEventStream" << std::endl;
143+ CFRelease (pathsToWatch);
144+ CFRelease (pathToWatch);
145+ return false ;
146+ }
147+ auto queue = dispatch_queue_create (nullptr , nullptr );
148+ FSEventStreamSetDispatchQueue (stream, queue);
136149 FSEventStreamStart (stream);
137- CFRunLoopRun (); // This will block until the stream is stopped.
138- FSEventStreamStop (stream);
139- FSEventStreamInvalidate (stream);
140- FSEventStreamRelease (stream);
141150 CFRelease (pathsToWatch);
142151 CFRelease (pathToWatch);
152+ return true ;
143153 }
144154
145155 void stop ()
146156 {
147- if (nullptr == runLoop ) {
157+ if (nullptr == stream ) {
148158 return ;
149159 }
150- if (CFRunLoopIsWaiting (runLoop) == 0U ) {
151- CFRunLoopWakeUp (runLoop);
152- }
153- CFRunLoopStop (runLoop);
160+ FSEventStreamStop (stream);
161+ FSEventStreamInvalidate (stream);
162+ FSEventStreamRelease (stream);
154163 }
155164
156- void run () { monitor (); }
165+ bool run () { return monitor (); }
157166
158167 MonitorDir *q_ptr;
159168
160- CFRunLoopRef runLoop = nullptr ;
169+ FSEventStreamRef stream = nullptr ;
161170
162171 std::filesystem::path dir;
163- std::thread monitorThread;
164172};
165173
166174MonitorDir::MonitorDir (const std::filesystem::path &dir)
@@ -179,29 +187,20 @@ MonitorDir::~MonitorDir()
179187
180188bool MonitorDir::start ()
181189{
182- if (m_isRunning) {
190+ if (m_isRunning. load () ) {
183191 std::cerr << " MonitorDir is already running" << std::endl;
184192 return false ;
185193 }
186-
187- m_isRunning.store (true );
188- d_ptr->monitorThread = std::thread ([this ] {
189- d_ptr->run ();
190- m_isRunning.store (false );
191- });
192-
193- return true ;
194+ m_isRunning.store (d_ptr->run ());
195+ return m_isRunning.load ();
194196}
195197
196198void MonitorDir::stop ()
197199{
198- if (!m_isRunning) {
200+ if (!m_isRunning. load () ) {
199201 std::cerr << " MonitorDir is not running" << std::endl;
200202 return ;
201203 }
202204
203205 d_ptr->stop ();
204- if (d_ptr->monitorThread .joinable ()) {
205- d_ptr->monitorThread .join ();
206- }
207206}
0 commit comments