Last active
June 3, 2025 03:23
-
-
Save swhitty/571deb25d84c1954a7a01aafa661496e to your computer and use it in GitHub Desktop.
Backports the Swift 6 type Mutex<Value> to all Apple platforms that support OSAllocatedUnfairLock
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Backports the Swift 6 type Mutex<Value> to all Darwin platforms via OSAllocatedUnfairLock. | |
// Lightweight version of https://github.com/swhitty/swift-mutex | |
// Feel free to use any part of this gist. | |
import struct os.OSAllocatedUnfairLock | |
// Backports the Swift 6.0 Mutex API | |
@available(iOS, introduced: 16.0, deprecated: 18.0, message: "use Mutex from Synchronization module") | |
@available(macOS, introduced: 13.0, deprecated: 15.0, message: "use Mutex from Synchronization module") | |
public struct Mutex<Value: ~Copyable>: @unchecked Sendable, ~Copyable { | |
private let lock = OSAllocatedUnfairLock() | |
private let storage: Storage | |
public init(_ initialValue: consuming sending Value) { | |
self.storage = Storage(initialValue) | |
} | |
public borrowing func withLock<Result, E: Error>( | |
_ body: (inout sending Value) throws(E) -> sending Result | |
) throws(E) -> sending Result { | |
lock.lock() | |
defer { lock.unlock() } | |
return try body(&storage.value) | |
} | |
public borrowing func withLockIfAvailable<Result, E: Error>( | |
_ body: (inout sending Value) throws(E) -> sending Result | |
) throws(E) -> sending Result? { | |
guard lock.lockIfAvailable() else { return nil } | |
defer { lock.unlock() } | |
return try body(&storage.value) | |
} | |
private final class Storage { | |
var value: Value | |
init(_ initialValue: consuming Value) { | |
self.value = initialValue | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment