Skip to content

Commit

Permalink
don't poll every second for kevents
Browse files Browse the repository at this point in the history
  • Loading branch information
gobbledegook committed Dec 25, 2023
1 parent e05fb38 commit 3f1014f
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 5 deletions.
2 changes: 1 addition & 1 deletion VDKQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ extern NSString * VDKQueueAccessRevocationNotification;
@private
int _coreQueueFD; // The actual kqueue ID (Unix file descriptor).
NSMutableDictionary *_watchedPathEntries; // List of VDKQueuePathEntries. Keys are NSStrings of the path that each VDKQueuePathEntry is for.
BOOL _keepWatcherThreadRunning; // Set to NO to cancel the thread that watches _coreQueueFD for kQueue events
BOOL _keepWatcherThreadRunning; // Keeps track of whether the thread is running or not.
}


Expand Down
14 changes: 10 additions & 4 deletions VDKQueue.m
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ - (VDKQueuePathEntry *) addPathToQueue:(NSString *)path notifyingAbout:(u_int)fl
{
_keepWatcherThreadRunning = YES;
[NSThread detachNewThreadSelector:@selector(watcherThread:) toTarget:self withObject:nil];
// register a custom event that we will trigger to stop the thread
kevent(_coreQueueFD, &(struct kevent){0, EVFILT_USER, EV_ADD, NOTE_FFNOP, 0, NULL}, 1, NULL, 0, &nullts);
}
}

Expand All @@ -212,7 +214,8 @@ - (void) watcherThread:(id)sender
{
int n;
struct kevent ev;
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.
// no timeout needed. Instead of polling every second, we can pass NULL to wait indefinitely
// for vnode events or for an EVFILT_USER event to stop the thread.
int theFD = _coreQueueFD; // So we don't have to risk accessing iVars when the thread is terminated.

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

while(_keepWatcherThreadRunning)
while(1)
{
@try
{
n = kevent(theFD, NULL, 0, &ev, 1, &timeout);
n = kevent(theFD, NULL, 0, &ev, 1, NULL);
if (ev.filter == EVFILT_USER) {
break;
}
if (n > 0)
{
//NSLog( @"KEVENT returned %d", n );
Expand Down Expand Up @@ -424,7 +430,7 @@ - (void) stopWatching
@synchronized(self)
{
// Shut down the thread that's scanning for kQueue events
_keepWatcherThreadRunning = NO;
kevent(_coreQueueFD, &(struct kevent){0, EVFILT_USER, EV_ENABLE, NOTE_TRIGGER, 0, NULL}, 1, NULL, 0, &(struct timespec){0,0});

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

0 comments on commit 3f1014f

Please sign in to comment.