Created
June 28, 2022 15:47
-
-
Save landonepps/1566fbabd9c623be272eef35d069786d to your computer and use it in GitHub Desktop.
An implementation of OSAllocatedUnfairLock for iOS 15 and earlier
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
// | |
// UnfairLock.swift | |
// Created by Epps, Landon on 6/28/22. | |
// | |
import Foundation | |
final class UnfairLock: NSLocking { | |
enum Ownership: Equatable, Hashable { | |
case owner, notOwner | |
} | |
let _lock: UnsafeMutablePointer<os_unfair_lock> | |
init() { | |
_lock = .allocate(capacity: 1) | |
_lock.initialize(to: os_unfair_lock()) | |
} | |
deinit { | |
_lock.deinitialize(count: 1) | |
_lock.deallocate() | |
} | |
func lock() { | |
os_unfair_lock_lock(_lock) | |
} | |
func lockIfAvailable() -> Bool { | |
return os_unfair_lock_trylock(_lock) | |
} | |
func unlock() { | |
os_unfair_lock_unlock(_lock) | |
} | |
func withLock<R>(_ body: () throws -> R) rethrows -> R { | |
lock() | |
defer { unlock() } | |
return try body() | |
} | |
func withLockIfAvailable<R>(_ body: () throws -> R) rethrows -> R? { | |
guard lockIfAvailable() else { return nil } | |
defer { unlock() } | |
return try body() | |
} | |
func precondition(_ condition: Ownership) { | |
switch condition { | |
case .owner: | |
os_unfair_lock_assert_owner(_lock) | |
case .notOwner: | |
os_unfair_lock_assert_not_owner(_lock) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment