Skip to content

Instantly share code, notes, and snippets.

@pauljohanneskraft
Last active July 1, 2016 00:23
Show Gist options
  • Save pauljohanneskraft/34e415c63dd114a6962b39e7395673ba to your computer and use it in GitHub Desktop.
Save pauljohanneskraft/34e415c63dd114a6962b39e7395673ba to your computer and use it in GitHub Desktop.
Atomic - locking a value using a NSLock-wrapper-struct

Atomic

var myAtomic = Atomic<Int>(5)
myAtomic.synced { $0 = 2 }
print( myAtomic.value )
// Prints "2"

Atomic is a generic wrapper-struct for values that need to be accessible safely, when working concurrently.

When accessing the value a NSLock will be locked, after accessing it will be unlocked.

"sync(_: f: @noescape(inout T) throws -> ()) rethrows" can be used to lock the value while running a block possibly changing the value.

private protocol AtomicProtocol {
associatedtype T
var lock : NSLock { get set }
var _value: T { get set }
var value: T { get set }
mutating func sync(_ f: @noescape(inout T) throws -> ()) rethrows
}
struct Atomic<T> : AtomicProtocol {
private var lock = NSLock()
private var _value: T
var value: T {
get {
lock.lock()
let val = _value
lock.unlock()
return val
}
set {
lock.lock()
_value = newValue
lock.unlock()
}
}
init(_ value: T) {
_value = value
}
mutating func synced<U>(_ f: @noescape(inout T) throws -> U) rethrows -> U {
lock.lock()
let e = try f(&_value)
lock.unlock()
return e
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment