diff options
| author | Aleksey Kladov <aleksey.kladov@gmail.com> | 2021-02-27 19:07:19 +0300 |
|---|---|---|
| committer | Aleksey Kladov <aleksey.kladov@gmail.com> | 2021-02-27 19:21:50 +0300 |
| commit | d94b4e81e4ce8bc21c192ed928f33991ffe78365 (patch) | |
| tree | 756ebf87c58cbe44c7bc1c88dfc2f4aca2318aa6 | |
| parent | 0846043440b480e4bbf36ac19db3948f0c835bb1 (diff) | |
| download | rust-d94b4e81e4ce8bc21c192ed928f33991ffe78365.tar.gz rust-d94b4e81e4ce8bc21c192ed928f33991ffe78365.zip | |
clarify RW lock's priority gotcha
In particular, the following program works on Linux, but deadlocks on
mac:
use std::{
sync::{Arc, RwLock},
thread,
time::Duration,
};
fn main() {
let lock = Arc::new(RwLock::new(()));
let r1 = thread::spawn({
let lock = Arc::clone(&lock);
move || {
let _rg = lock.read();
eprintln!("r1/1");
sleep(1000);
let _rg = lock.read();
eprintln!("r1/2");
sleep(5000);
}
});
sleep(100);
let w = thread::spawn({
let lock = Arc::clone(&lock);
move || {
let _wg = lock.write();
eprintln!("w");
}
});
sleep(100);
let r2 = thread::spawn({
let lock = Arc::clone(&lock);
move || {
let _rg = lock.read();
eprintln!("r2");
sleep(2000);
}
});
r1.join().unwrap();
r2.join().unwrap();
w.join().unwrap();
}
fn sleep(ms: u64) {
std::thread::sleep(Duration::from_millis(ms))
}
| -rw-r--r-- | library/std/src/sync/rwlock.rs | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index d967779ce36..4e706b27096 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -23,7 +23,9 @@ use crate::sys_common::rwlock as sys; /// /// The priority policy of the lock is dependent on the underlying operating /// system's implementation, and this type does not guarantee that any -/// particular policy will be used. +/// particular policy will be used. In particular, a writer which is waiting to +/// acquire the lock in `write` might or might not block future calls to +/// `read`. /// /// The type parameter `T` represents the data that this lock protects. It is /// required that `T` satisfies [`Send`] to be shared across threads and |
