Skip to content

Instantly share code, notes, and snippets.

@swhitty
Last active April 18, 2023 02:07
Show Gist options
  • Select an option

  • Save swhitty/5c1edc9bd5dc0cd7650ccf1c14bbe32e to your computer and use it in GitHub Desktop.

Select an option

Save swhitty/5c1edc9bd5dc0cd7650ccf1c14bbe32e to your computer and use it in GitHub Desktop.
@_implementationOnly import os
// Backports the Swift interface around os_unfair_lock_t available in recent Darwin platforms
//
@available(iOS, deprecated: 16.0, message: "use OSAllocatedUnfairLock directly")
@available(tvOS, deprecated: 16.0, message: "use OSAllocatedUnfairLock directly")
@available(watchOS, deprecated: 9, message: "use OSAllocatedUnfairLock directly")
@available(macOS, deprecated: 13.0, message: "use OSAllocatedUnfairLock directly")
struct AllocatedUnfairLock<State> {
private let storage: Storage
init(initialState: State) {
self.storage = Storage(initialState: initialState)
}
func withLock<R>(_ body: @Sendable (inout State) throws -> R) rethrows -> R where R: Sendable {
os_unfair_lock_lock(storage.lock)
defer { os_unfair_lock_unlock(storage.lock) }
return try body(&storage.state)
}
private final class Storage {
let lock: os_unfair_lock_t
var state: State
init(initialState: State) {
self.lock = .allocate(capacity: 1)
self.lock.initialize(to: os_unfair_lock())
self.state = initialState
}
deinit {
self.lock.deinitialize(count: 1)
self.lock.deallocate()
}
}
}
extension AllocatedUnfairLock where State == Void {
init() {
self.storage = .init(initialState: ())
}
func lock() {
os_unfair_lock_lock(storage.lock)
}
func unlock() {
os_unfair_lock_unlock(storage.lock)
}
func withLock<R>(_ body: @Sendable () throws -> R) rethrows -> R where R: Sendable {
os_unfair_lock_lock(storage.lock)
defer { os_unfair_lock_unlock(storage.lock) }
return try body()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment