Replace NSLock with Mutex (#193)

This PR replaces `NSLock` with `Mutex`. Thanks @dcantah for the idea!
This commit is contained in:
Dmitry Kovba
2025-07-03 16:11:38 -07:00
committed by GitHub
parent 9775528495
commit 969703d9ad
+11 -10
View File
@@ -14,8 +14,8 @@
// limitations under the License.
//===----------------------------------------------------------------------===//
// `Foundation` will be automatically imported with `SendableProperty`.
@_exported import Foundation
// `Synchronization` will be automatically imported with `SendableProperty`.
@_exported import Synchronization
// A declaration of the `@SendableProperty` macro.
@attached(peer, names: arbitrary)
@@ -23,23 +23,24 @@
public macro SendableProperty() = #externalMacro(module: "SendablePropertyMacros", type: "SendablePropertyMacro")
/// A synchronization primitive that protects shared mutable state via mutual exclusion.
public final class Synchronized<T>: @unchecked Sendable {
private let lock = NSLock()
private var value: T
public final class Synchronized<T>: Sendable {
private let lock: Mutex<State>
private struct State: @unchecked Sendable {
var value: T
}
/// Creates a new instance.
/// - Parameter value: The initial value.
public init(_ value: T) {
self.value = value
self.lock = Mutex(State(value: value))
}
/// Calls the given closure after acquiring the lock and returns its value.
/// - Parameter body: The body of code to execute while the lock is held.
public func withLock<R>(_ body: (inout T) throws -> R) rethrows -> R {
lock.lock()
defer {
lock.unlock()
try lock.withLock { state in
try body(&state.value)
}
return try body(&value)
}
}