From a8d7fb017fd677f7e070d373a037c7e263880003 Mon Sep 17 00:00:00 2001 From: "T. R. Bernstein" Date: Thu, 12 Mar 2026 10:54:06 +0100 Subject: [PATCH] Add data structure for watch descriptor management For watching whole trees - a change which is upcoming - the watch descriptor IDs will have to be managed in multiple lists. The InotifyWatchManager encapsulates the managment logic within a nice API. --- Sources/Inotify/Inotify.swift | 8 ++++---- Sources/Inotify/InotifyWatchManager.swift | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 Sources/Inotify/InotifyWatchManager.swift diff --git a/Sources/Inotify/Inotify.swift b/Sources/Inotify/Inotify.swift index 3b079cb..3a85681 100644 --- a/Sources/Inotify/Inotify.swift +++ b/Sources/Inotify/Inotify.swift @@ -3,7 +3,7 @@ import CInotify public actor Inotify { private let fd: CInt - private var watches: [CInt: String] = [:] + private var watches = InotifyWatchManager() private var eventReader: any DispatchSourceRead private var eventStream: AsyncStream public var events: AsyncCompactMapSequence, InotifyEvent> { @@ -24,7 +24,7 @@ public actor Inotify { guard wd >= 0 else { throw InotifyError.addWatchFailed(path: path, errno: cinotify_get_errno()) } - watches[wd] = path + watches.add(path, withId: wd) return wd } @@ -43,7 +43,7 @@ public actor Inotify { guard inotify_rm_watch(self.fd, wd) == 0 else { throw InotifyError.removeWatchFailed(watchDescriptor: wd, errno: cinotify_get_errno()) } - watches.removeValue(forKey: wd) + watches.remove(forId: wd) } deinit { @@ -51,7 +51,7 @@ public actor Inotify { } private func transform(_ rawEvent: RawInotifyEvent) -> InotifyEvent? { - guard let path = self.watches[rawEvent.watchDescriptor] else { return nil } + guard let path = self.watches.path(forId: rawEvent.watchDescriptor) else { return nil } return InotifyEvent.init(from: rawEvent, inDirectory: path) } diff --git a/Sources/Inotify/InotifyWatchManager.swift b/Sources/Inotify/InotifyWatchManager.swift new file mode 100644 index 0000000..4d1d926 --- /dev/null +++ b/Sources/Inotify/InotifyWatchManager.swift @@ -0,0 +1,18 @@ +struct InotifyWatchManager { + private var watchPaths: [CInt: String] = [:] + private var activeWatches: Set = [] + + mutating func add(_ path: String, withId watchDescriptor: CInt) { + self.watchPaths[watchDescriptor] = path + self.activeWatches.insert(watchDescriptor) + } + + mutating func remove(forId watchDescriptor: CInt) { + self.watchPaths.removeValue(forKey: watchDescriptor) + self.activeWatches.remove(watchDescriptor) + } + + func path(forId watchDescriptor: CInt) -> String? { + return self.watchPaths[watchDescriptor] + } +}