Backport mutex

This commit is contained in:
Max Goedjen 2025-01-05 16:25:16 -08:00
parent 576e625b8f
commit 9b02afb20c
No known key found for this signature in database
9 changed files with 60 additions and 15 deletions

View File

@ -27,18 +27,26 @@ let package = Package(
.library(
name: "Brief",
targets: ["Brief"]),
.library(
name: "Backports",
targets: ["Backports"]),
],
dependencies: [
],
targets: [
.target(
name: "SecretKit",
name: "Backports",
dependencies: [],
swiftSettings: swiftSettings
),
.target(
name: "SecretKit",
dependencies: ["Backports"],
swiftSettings: swiftSettings
),
.testTarget(
name: "SecretKitTests",
dependencies: ["SecretKit", "SecureEnclaveSecretKit", "SmartCardSecretKit"],
dependencies: ["Backports", "SecretKit", "SecureEnclaveSecretKit", "SmartCardSecretKit"],
swiftSettings: swiftSettings
),
.target(
@ -48,12 +56,12 @@ let package = Package(
),
.target(
name: "SmartCardSecretKit",
dependencies: ["SecretKit"],
dependencies: ["Backports", "SecretKit"],
swiftSettings: swiftSettings
),
.target(
name: "SecretAgentKit",
dependencies: ["SecretKit", "SecretAgentKitHeaders"],
dependencies: ["Backports", "SecretKit", "SecretAgentKitHeaders"],
swiftSettings: swiftSettings
),
.systemLibrary(
@ -65,7 +73,7 @@ let package = Package(
,
.target(
name: "Brief",
dependencies: []
dependencies: ["Backports"]
),
.testTarget(
name: "BriefTests",

View File

@ -0,0 +1,30 @@
import Foundation
#if canImport(Synchronization)
import Synchronization
public typealias _Mutex = Mutex
#else
import os
public final class _Mutex<Value: ~Copyable>: @unchecked Sendable {
private var value: Value
private var lock = OSAllocatedUnfairLock()
public init(_ value: consuming sending Value) {
self.value = value
}
public borrowing func withLock<Result, E>(_ body: (inout sending Value) throws(E) -> sending Result) throws(E) -> sending Result where E : Error, Result : ~Copyable {
lock.lock()
defer {
lock.unlock()
}
return try body(&value)
}
}
#endif

View File

@ -1,6 +1,7 @@
import Foundation
import Observation
import Synchronization
import Backports
/// A concrete implementation of ``UpdaterProtocol`` which considers the current release and OS version.
@Observable public final class Updater: UpdaterProtocol, ObservableObject, Sendable {
@ -8,7 +9,7 @@ import Synchronization
public var update: Release? {
_update.withLock { $0 }
}
private let _update: Mutex<Release?> = .init(nil)
private let _update: _Mutex<Release?> = .init(nil)
public let testBuild: Bool
/// The current OS version.

View File

@ -1,6 +1,7 @@
import Foundation
import OSLog
import Synchronization
import Backports
/// Manages storage and lookup for OpenSSH certificates.
public final class OpenSSHCertificateHandler: Sendable {
@ -8,7 +9,7 @@ public final class OpenSSHCertificateHandler: Sendable {
private let publicKeyFileStoreController = PublicKeyFileStoreController(homeDirectory: NSHomeDirectory())
private let logger = Logger(subsystem: "com.maxgoedjen.secretive.secretagent", category: "OpenSSHCertificateHandler")
private let writer = OpenSSHKeyWriter()
private let keyBlobsAndNames: Mutex<[AnySecret: (Data, Data)]> = .init([:])
private let keyBlobsAndNames: _Mutex<[AnySecret: (Data, Data)]> = .init([:])
/// Initializes an OpenSSHCertificateHandler.
public init() {

View File

@ -1,6 +1,7 @@
import Foundation
import Observation
import Synchronization
import Backports
/// A "Store Store," which holds a list of type-erased stores.
@Observable public final class SecretStoreList: Sendable {
@ -9,13 +10,13 @@ import Synchronization
public var stores: [AnySecretStore] {
__stores.withLock { $0 }
}
private let __stores: Mutex<[AnySecretStore]> = .init([])
private let __stores: _Mutex<[AnySecretStore]> = .init([])
/// A modifiable store, if one is available.
public var modifiableStore: AnySecretStoreModifiable? {
__modifiableStore.withLock { $0 }
}
private let __modifiableStore: Mutex<AnySecretStoreModifiable?> = .init(nil)
private let __modifiableStore: _Mutex<AnySecretStoreModifiable?> = .init(nil)
/// Initializes a SecretStoreList.
public init() {

View File

@ -5,6 +5,7 @@ import CryptoKit
import LocalAuthentication
import SecretKit
import Synchronization
import Backports
extension SecureEnclave {
@ -19,9 +20,9 @@ extension SecureEnclave {
public var secrets: [Secret] {
_secrets.withLock { $0 }
}
private let _secrets: Mutex<[Secret]> = .init([])
private let _secrets: _Mutex<[Secret]> = .init([])
private let persistedAuthenticationContexts: Mutex<[Secret: PersistentAuthenticationContext]> = .init([:])
private let persistedAuthenticationContexts: _Mutex<[Secret: PersistentAuthenticationContext]> = .init([:])
/// Initializes a Store.
public init() {
@ -105,7 +106,7 @@ extension SecureEnclave {
}
public func sign(data: Data, with secret: Secret, for provenance: SigningRequestProvenance) throws -> Data {
let context: Mutex<LAContext>
let context: _Mutex<LAContext>
// if let existing = persistedAuthenticationContexts.withLock({ $0 })[secret], existing.valid {
// context = existing.context
// } else {

View File

@ -5,6 +5,7 @@ import Security
import CryptoTokenKit
import LocalAuthentication
import SecretKit
import Backports
extension SmartCard {
@ -19,7 +20,7 @@ extension SmartCard {
/// An implementation of Store backed by a Smart Card.
@Observable public final class Store: SecretStore {
private let state: Mutex<State> = .init(.init())
private let state: _Mutex<State> = .init(.init())
public var isAvailable: Bool {
state.withLock { $0.isAvailable }
}

View File

@ -5,6 +5,7 @@ import SecretKit
import SecretAgentKit
import Brief
import Synchronization
import Backports
final class Notifier: Sendable {
@ -151,7 +152,7 @@ final class NotificationDelegate: NSObject, UNUserNotificationCenterDelegate, Se
fileprivate var pendingPersistableSecrets: [String: AnySecret] = [:]
}
fileprivate let state: Mutex<State> = .init(.init())
fileprivate let state: _Mutex<State> = .init(.init())
func userNotificationCenter(_ center: UNUserNotificationCenter, openSettingsFor notification: UNNotification?) {

View File

@ -2,13 +2,14 @@ import Foundation
import Synchronization
import Observation
import Brief
import Backports
@Observable class PreviewUpdater: UpdaterProtocol {
var update: Release? {
_update.withLock { $0 }
}
let _update: Mutex<Release?> = .init(nil)
let _update: _Mutex<Release?> = .init(nil)
let testBuild = false