1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-01-03 05:25:52 +00:00

perf: Don't poll every second for kevents (#6452)

* perf: Don't poll every second for kevents

* No need to alter properties in dealloc
This commit is contained in:
Cœur 2023-12-31 22:17:31 +01:00 committed by GitHub
parent e5e768e2ab
commit f8f68067d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 12 deletions

View file

@ -86,6 +86,8 @@
//
// - macOS 10.10+: DispatchSource API (makeFileSystemObjectSource)
// (https://developer.apple.com/documentation/dispatch/dispatchsource/2300040-makefilesystemobjectsource)
// "DispatchSource is just the Swift version of gcd dispatch sources"
// (https://github.com/bdkjones/VDKQueue/pull/22#issuecomment-1871623127)
//
// Example: SFSMonitor (https://github.com/ClassicalDude/SFSMonitor)

View file

@ -39,8 +39,8 @@ NSString const* VDKQueueAccessRevocationNotification = @"VDKQueueAccessWasRevoke
/// This is a simple model class used to hold info about each path we watch.
@interface VDKQueuePathEntry : NSObject
@property(atomic, copy) NSString* path;
@property(atomic, assign) int watchedFD;
@property(atomic, copy, readonly) NSString* path;
@property(atomic, assign, readonly) int watchedFD;
@property(atomic, assign) u_int subscriptionFlags;
@end
@ -69,7 +69,6 @@ NSString const* VDKQueueAccessRevocationNotification = @"VDKQueueAccessWasRevoke
{
close(_watchedFD);
}
_watchedFD = -1;
}
@end
@ -147,7 +146,6 @@ NSString const* VDKQueueAccessRevocationNotification = @"VDKQueueAccessWasRevoke
{
struct timespec nullts = { 0, 0 };
struct kevent ev;
EV_SET(&ev, pathEntry.watchedFD, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, flags, 0, (__bridge void*)pathEntry);
pathEntry.subscriptionFlags = flags;
@ -176,16 +174,13 @@ NSString const* VDKQueueAccessRevocationNotification = @"VDKQueueAccessWasRevoke
NSThread.currentThread.name = @"VDKQueue";
struct kevent ev;
// 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.
const struct timespec timeout = { 1, 0 };
// So we don't have to risk accessing iVars when the thread is terminated.
int const theFD = _coreQueueFD;
NSMutableArray* notesToPost = [[NSMutableArray alloc] initWithCapacity:5];
while (_keepWatcherThreadRunning)
{
int n = kevent(theFD, NULL, 0, &ev, 1, &timeout);
int n = kevent(theFD, NULL, 0, &ev, 1, NULL);
if (n <= 0 || ev.filter != EVFILT_VNODE || !ev.fflags)
{
continue;
@ -294,6 +289,17 @@ NSString const* VDKQueueAccessRevocationNotification = @"VDKQueueAccessWasRevoke
}
}
/// Shut down the thread that's scanning for kQueue events.
- (void)shutdownWatcherThread
{
_keepWatcherThreadRunning = NO;
// Trigger a custom event to stop the thread.
struct timespec nullts = { 0, 0 };
struct kevent stopEvent = { 0, EVFILT_USER, EV_ADD | EV_ONESHOT, NOTE_TRIGGER, 0, NULL };
kevent(_coreQueueFD, &stopEvent, 1, NULL, 0, &nullts);
}
- (void)removePath:(NSString*)aPath
{
if (!aPath)
@ -310,8 +316,7 @@ NSString const* VDKQueueAccessRevocationNotification = @"VDKQueueAccessWasRevoke
if (_watchedPathEntries.count == 0)
{
// Shut down the thread that's scanning for kQueue events.
_keepWatcherThreadRunning = NO;
[self shutdownWatcherThread];
}
}
}
@ -323,8 +328,7 @@ NSString const* VDKQueueAccessRevocationNotification = @"VDKQueueAccessWasRevoke
// Close all the open file descriptors for files we're watching.
[_watchedPathEntries removeAllObjects];
// Shut down the thread that's scanning for kQueue events.
_keepWatcherThreadRunning = NO;
[self shutdownWatcherThread];
}
}