Instantly share code, notes, and snippets.

Embed
What would you like to do?
Using locks as signals and for mutual exclusion
import Foundation
/// A class to model a room.
final class Room {
// Counter
private(set) var count: Int = 0
// Lock to protect mutation of our counter
private var lock = os_unfair_lock_s()
// Someone has entered the room; increment the counter
func enter() {
os_unfair_lock_lock(&lock)
count += 1
os_unfair_lock_unlock(&lock)
}
// Someone has left the room; decrement the counter
func leave() {
os_unfair_lock_lock(&lock)
count -= 1
os_unfair_lock_unlock(&lock)
}
}
let aspenBallroom = Room()
// Main door
let agnes = DispatchQueue(label: "Agnes")
let agnesLock = NSLock()
agnesLock.lock()
agnes.async {
for _ in 1...6000 {
aspenBallroom.enter()
}
print("Agnes is done")
agnesLock.unlock()
}
// Side door
let tammy = DispatchQueue(label: "Tammy")
let tammyLock = NSLock()
tammyLock.lock()
tammy.async {
for _ in 1...4000 {
aspenBallroom.enter()
}
print("Tammy is done")
tammyLock.unlock()
}
// Emergency exit
let sam = DispatchQueue(label: "sam")
let samLock = NSLock()
samLock.lock()
sam.async {
for _ in 1...1000 {
aspenBallroom.leave()
}
print("sam is done")
samLock.unlock()
}
// Acquire all the locks, ensuring all our resources have completed their jobs
samLock.lock()
agnesLock.lock()
tammyLock.lock()
// Use the counter
print("Count: \(aspenBallroom.count)")
// Release the locks
samLock.unlock()
agnesLock.unlock()
tammyLock.unlock()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment