TM-SGNL-iOS/SignalServiceKit/Storage/Database/SDSCrossProcess.swift
TeleMessage developers dde0620daf initial commit
2025-05-03 12:28:28 -07:00

48 lines
1.8 KiB
Swift

//
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
/// This class can be used by ``SDSDatabaseStorage`` to learn of
/// database writes by other processes.
///
/// * `notifyChanged` should be called after every write
/// transaction completes.
/// * `callback` is invoked when a write from another process
/// is detected.
final class SDSCrossProcess: Sendable {
private let notifyTokens: [DarwinNotificationCenter.ObserverToken]
init(callback: @escaping @Sendable @MainActor () -> Void) {
var notifyTokens: [DarwinNotificationCenter.ObserverToken] = []
let block = { (_: DarwinNotificationCenter.ObserverToken) -> Void in
// the addObserver calls below execute this block on the main thread so we should already be isolated
// but there's no way to tell the compiler this with these old APIs, so we tell it to assume we are.
MainActor.assumeIsolated {
callback()
}
}
// listen to everyone but our self; then when posting post our own type
let currentAppContextType = CurrentAppContext().type
for appContextType in AppContextType.allCases {
if appContextType == currentAppContextType { continue }
notifyTokens.append(DarwinNotificationCenter.addObserver(name: .sdsCrossProcess(for: appContextType), queue: .main, block: block))
}
self.notifyTokens = notifyTokens
}
deinit {
for notifyToken in notifyTokens {
if DarwinNotificationCenter.isValid(notifyToken) {
DarwinNotificationCenter.removeObserver(notifyToken)
}
}
}
@MainActor
func notifyChanged() {
DarwinNotificationCenter.postNotification(name: .sdsCrossProcess(for: CurrentAppContext().type))
}
}