Skip to content

Instantly share code, notes, and snippets.

@einsteinx2
Forked from kristopherjohnson/locking.swift
Last active March 2, 2019 17:25
Show Gist options
  • Save einsteinx2/00b9ebd962f3a0f6c9e758f842e4c6f9 to your computer and use it in GitHub Desktop.
Save einsteinx2/00b9ebd962f3a0f6c9e758f842e4c6f9 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
}
@einsteinx2
Copy link
Author

Updated for Swift 3

@omarojo
Copy link

omarojo commented May 5, 2017

Hi, what would be the best function to use.. for a case where I need to lock a property variable from been written when someone else is reading it ?

I have a timer that pushes a CVPIxelBuffer (self.myPB) to a streaming library, but its giving a EXC_BAD_ACCESS. I belive is because self.myPB gets rewritten by a closure. So someone else is rewriting self.myPB while the timer triggers and tries to append the pixelbuffer to the library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment