Skip to content

Commit 3f1014f

Browse files
committed
don't poll every second for kevents
1 parent e05fb38 commit 3f1014f

2 files changed

Lines changed: 11 additions & 5 deletions

File tree

VDKQueue.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ extern NSString * VDKQueueAccessRevocationNotification;
124124
@private
125125
int _coreQueueFD; // The actual kqueue ID (Unix file descriptor).
126126
NSMutableDictionary *_watchedPathEntries; // List of VDKQueuePathEntries. Keys are NSStrings of the path that each VDKQueuePathEntry is for.
127-
BOOL _keepWatcherThreadRunning; // Set to NO to cancel the thread that watches _coreQueueFD for kQueue events
127+
BOOL _keepWatcherThreadRunning; // Keeps track of whether the thread is running or not.
128128
}
129129

130130

VDKQueue.m

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ - (VDKQueuePathEntry *) addPathToQueue:(NSString *)path notifyingAbout:(u_int)fl
194194
{
195195
_keepWatcherThreadRunning = YES;
196196
[NSThread detachNewThreadSelector:@selector(watcherThread:) toTarget:self withObject:nil];
197+
// register a custom event that we will trigger to stop the thread
198+
kevent(_coreQueueFD, &(struct kevent){0, EVFILT_USER, EV_ADD, NOTE_FFNOP, 0, NULL}, 1, NULL, 0, &nullts);
197199
}
198200
}
199201

@@ -212,7 +214,8 @@ - (void) watcherThread:(id)sender
212214
{
213215
int n;
214216
struct kevent ev;
215-
struct timespec timeout = { 1, 0 }; // 1 second timeout. Should be longer, but we need this thread to exit when a kqueue is dealloced, so 1 second timeout is quite a while to wait.
217+
// no timeout needed. Instead of polling every second, we can pass NULL to wait indefinitely
218+
// for vnode events or for an EVFILT_USER event to stop the thread.
216219
int theFD = _coreQueueFD; // So we don't have to risk accessing iVars when the thread is terminated.
217220

218221
NSMutableArray *notesToPost = [[NSMutableArray alloc] initWithCapacity:5];
@@ -221,11 +224,14 @@ - (void) watcherThread:(id)sender
221224
NSLog(@"watcherThread started.");
222225
#endif
223226

224-
while(_keepWatcherThreadRunning)
227+
while(1)
225228
{
226229
@try
227230
{
228-
n = kevent(theFD, NULL, 0, &ev, 1, &timeout);
231+
n = kevent(theFD, NULL, 0, &ev, 1, NULL);
232+
if (ev.filter == EVFILT_USER) {
233+
break;
234+
}
229235
if (n > 0)
230236
{
231237
//NSLog( @"KEVENT returned %d", n );
@@ -424,7 +430,7 @@ - (void) stopWatching
424430
@synchronized(self)
425431
{
426432
// Shut down the thread that's scanning for kQueue events
427-
_keepWatcherThreadRunning = NO;
433+
kevent(_coreQueueFD, &(struct kevent){0, EVFILT_USER, EV_ENABLE, NOTE_TRIGGER, 0, NULL}, 1, NULL, 0, &(struct timespec){0,0});
428434

429435
// Do this to close all the open file descriptors for files we're watching
430436
[_watchedPathEntries removeAllObjects];

0 commit comments

Comments
 (0)