Skip to content

Instantly share code, notes, and snippets.

@greggjaskiewicz
Created November 25, 2020 13:37
Show Gist options
  • Save greggjaskiewicz/5d0d6e82c3865dd9da5a514cf9b3b5b8 to your computer and use it in GitHub Desktop.
Save greggjaskiewicz/5d0d6e82c3865dd9da5a514cf9b3b5b8 to your computer and use it in GitHub Desktop.
atomic properties in swift.
fileprivate final class ReadWriteLock {
private var rwlock: pthread_rwlock_t = {
var rwlock = pthread_rwlock_t()
pthread_rwlock_init(&rwlock, nil)
return rwlock
}()
func writeLock() {
pthread_rwlock_wrlock(&(self.rwlock))
}
func readLock() {
pthread_rwlock_rdlock(&(self.rwlock))
}
func unlock() {
pthread_rwlock_unlock(&(self.rwlock))
}
}
final class AtomicPropertyContainer<T> {
typealias DidSetBlock = (_: T)->Void
private var internalValue: T
private let lock = ReadWriteLock()
private let didSetBlock: DidSetBlock?
init(_ initialValue: T, didSetBlock: DidSetBlock? = nil) {
self.internalValue = initialValue
self.didSetBlock = didSetBlock
}
var value: T {
get {
self.lock.readLock()
let value = self.internalValue
self.lock.unlock()
return value
}
set {
self.lock.writeLock()
self.internalValue = newValue
self.lock.unlock()
if let block = self.didSetBlock {
DispatchQueue.global(qos: .default) .async {
block(newValue)
}
}
}
}
}
final class AtomicWrappedPropertyContainer<T> {
typealias DidSetBlock = (_: T?)->Void
private var internalValue: T?
private let lock = ReadWriteLock()
private let didSetBlock: DidSetBlock?
init(_ initialValue: T? = nil, didSetBlock: DidSetBlock? = nil) {
self.internalValue = initialValue
self.didSetBlock = didSetBlock
}
var value: T? {
get {
self.lock.readLock()
let currentValue = self.internalValue
self.lock.unlock()
return currentValue
}
set {
self.lock.writeLock()
self.internalValue = newValue
self.lock.unlock()
if let block = self.didSetBlock {
DispatchQueue.global(qos: .default) .async {
block(newValue)
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment