Skip to content

Instantly share code, notes, and snippets.

@tapoton
Created May 14, 2025 17:43
Show Gist options
  • Select an option

  • Save tapoton/f3507c4199ff1c6aaa8d846e3cc0749a to your computer and use it in GitHub Desktop.

Select an option

Save tapoton/f3507c4199ff1c6aaa8d846e3cc0749a to your computer and use it in GitHub Desktop.
Data race demo
import Foundation
import Synchronization
final class Counter: Sendable {
private let mutex = Mutex(0)
var count: Int {
get {
return mutex.withLock { count in
return count
}
}
}
func setCount(_ newCount: Int) {
mutex.withLock { count in
count = newCount
}
}
func increment() {
setCount(count + 1)
}
}
let counter = Counter()
await withTaskGroup { group in
for _ in 0..<1000 {
group.addTask {
counter.increment()
}
}
await group.waitForAll()
}
print(counter.count)
@tapoton
Copy link
Author

tapoton commented May 14, 2025

It's safe like this:

final class Counter: Sendable {
    private let mutex = Mutex(0)
    
    var count: Int {
        get {
            return mutex.withLock { count in
                return count
            }
        }
    }
    
    func updateCount(_ update: (inout Int) -> Void) {
        mutex.withLock { count in
            update(&count)
        }
    }

    func increment() {
        updateCount { $0 += 1 }
    }
}

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