A station's departure board is read by dozens of passenger screens at once, and now and then the dispatcher pushes an update (a delay, a platform change). With the plain reader-writer lock from Basics, a busy station has a problem: screens keep arriving, some screen is always inside, and the dispatcher's update never goes out.
Implement WriterFirstLock, a reader-writer lock that prefers writers:
acquire_read(): block while a writer holds the lock or while any writer is waiting for it, then enter as a reader. Readers still share the lock with each other.release_read(): leave as a reader.acquire_write(): announce that you are waiting, block until nobody holds the lock (no readers, no writer), then enter as the only writer.release_write(): leave as the writer.
Readers already inside when a writer starts waiting finish normally; only new readers are held back.
rw = WriterFirstLock()
# screen S1: rw.acquire_read() -> gets in
# dispatcher: rw.acquire_write() -> waits for S1
# screen S2: rw.acquire_read() -> blocks too: a writer is waiting
# S1: rw.release_read() -> dispatcher gets in, updates, release_write()
# -> only now does S2 get in
If several writers are waiting, they may all go before the held-back readers. Callers always pair each acquire with the matching release, and a thread never takes the read lock twice. Don't sleep or busy-wait.
Show hint
Add a waiting_writers count to the Basics design. A writer increments it before wait_for(not writer and readers == 0) and decrements it once inside; readers wait_for(not writer and waiting_writers == 0); every release calls notify_all().