Skip to content

Instantly share code, notes, and snippets.

@szotp
Last active February 18, 2020 13:52
Show Gist options
  • Save szotp/b21dbfee1f4d6f66f8f5b434e76c32eb to your computer and use it in GitHub Desktop.
Save szotp/b21dbfee1f4d6f66f8f5b434e76c32eb to your computer and use it in GitHub Desktop.
Demonstration of struct usage with threading
import Foundation
/// If T is a struct, then this class provides thread safety, because all reads and writes happen inside queue.
/// But, if T is very big, copying it may decrease performance.
class SafeAccess<T> {
private let queue = DispatchQueue(label: "Safe")
private var _value: T
init(_ value: T) {
_value = value
}
var value: T {
get {
var result: T!
queue.sync {
result = _value // entire struct will be copied
}
return result
}
}
func modify(_ closure: (inout T) -> Void) {
queue.sync {
closure(&_value)
}
}
}
func example() {
struct Foo {
var x = 0
}
let access = SafeAccess(Foo())
for _ in 0..<100 {
DispatchQueue.global().async {
let x = access.value.x
let computedState1 = x + 1
access.modify {
let computedState2 = $0.x + 1
$0.x = computedState2
if computedState1 != computedState2 {
print("Potential inconsitency \(computedState1) != \(computedState2)")
}
print("Incremented to \(computedState2)")
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment