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