Skip to content

Instantly share code, notes, and snippets.

@swhitty
Last active June 3, 2025 03:23
Show Gist options
  • Save swhitty/571deb25d84c1954a7a01aafa661496e to your computer and use it in GitHub Desktop.
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
// 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