Skip to content

Instantly share code, notes, and snippets.

@landonepps
Created June 28, 2022 15:47
Show Gist options
  • Save landonepps/1566fbabd9c623be272eef35d069786d to your computer and use it in GitHub Desktop.
Save landonepps/1566fbabd9c623be272eef35d069786d to your computer and use it in GitHub Desktop.
An implementation of OSAllocatedUnfairLock for iOS 15 and earlier
//
// 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