Skip to content

Instantly share code, notes, and snippets.

@alejoberman
Forked from einsteinx2/locking.swift
Created May 19, 2017 08:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alejoberman/678e3878e7dec605ad318924f8ff8376 to your computer and use it in GitHub Desktop.
Save alejoberman/678e3878e7dec605ad318924f8ff8376 to your computer and use it in GitHub Desktop.
Simple synchronization functions for Swift, wrapping the Cocoa NSLocking classes
import Foundation
/// Protocol for NSLocking objects that also provide try()
public protocol TryLockable: NSLocking {
func `try`() -> Bool
}
// These Cocoa classes have tryLock()
extension NSLock: TryLockable {}
extension NSRecursiveLock: TryLockable {}
extension NSConditionLock: TryLockable {}
/// Protocol for NSLocking objects that also provide lock(before limit: Date)
public protocol BeforeDateLockable: NSLocking {
func lock(before limit: Date) -> Bool
}
// These Cocoa classes have lockBeforeDate()
extension NSLock: BeforeDateLockable {}
extension NSRecursiveLock: BeforeDateLockable {}
extension NSConditionLock: BeforeDateLockable {}
/// Use an NSLocking object as a mutex for a critical section of code
public func synchronized<L: NSLocking>(lockable: L, criticalSection: () -> ()) {
lockable.lock()
criticalSection()
lockable.unlock()
}
/// Use an NSLocking object as a mutex for a critical section of code that returns a result
public func synchronizedResult<L: NSLocking, T>(lockable: L, criticalSection: () -> T) -> T {
lockable.lock()
let result = criticalSection()
lockable.unlock()
return result
}
/// Use a TryLockable object as a mutex for a critical section of code
///
/// Return true if the critical section was executed, or false if tryLock() failed
public func trySynchronized<L: TryLockable>(lockable: L, criticalSection: () -> ()) -> Bool {
if !lockable.try() {
return false
}
criticalSection()
lockable.unlock()
return true
}
/// Use a BeforeDateLockable object as a mutex for a critical section of code
///
/// Return true if the critical section was executed, or false if lockBeforeDate() failed
public func synchronizedBeforeDate<L: BeforeDateLockable>(limit: Date, lockable: L, criticalSection: () -> ()) -> Bool {
if !lockable.lock(before: limit) {
return false
}
criticalSection()
lockable.unlock()
return true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment