mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Rollup merge of #153555 - asder8215:rwlock_docs, r=Mark-Simulacrum
Clarified docs in std::sync::RwLock + added test to ensure that max reader count is respected This addresses the issue with the [`std::sync::RwLock` docs](https://doc.rust-lang.org/std/sync/struct.RwLock.html) in rust-lang/rust#115338. It centers around the following lines: > An `RwLock` will allow any number of readers to acquire the lock as long as a writer is not holding the lock. It's true that the `RwLock` in theory should allow any number of readers to acquire the lock when a writer is not holding it, but this may not be true in the implementation and could be os dependent. I decided to replace "any number of readers" to "multiple", so that it implies that more than 1 reader can acquire the lock, but you can't necessarily take away that this value is unbounded. @rustbot label +A-docs
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
///
|
||||
/// In comparison, a [`Mutex`] does not distinguish between readers or writers
|
||||
/// that acquire the lock, therefore blocking any threads waiting for the lock to
|
||||
/// become available. An `RwLock` will allow any number of readers to acquire the
|
||||
/// become available. An `RwLock` will allow multiple readers to acquire the
|
||||
/// lock as long as a writer is not holding the lock.
|
||||
///
|
||||
/// The priority policy of the lock is dependent on the underlying operating
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Arc, MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
|
||||
TryLockError,
|
||||
};
|
||||
use std::{hint, mem, thread};
|
||||
use std::{hint, mem, thread, u32};
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
@@ -883,3 +883,66 @@ fn test_rwlock_with_mut() {
|
||||
assert_eq!(*rwlock.read(), 5);
|
||||
assert_eq!(result, 10);
|
||||
}
|
||||
|
||||
// To note: there are (currently) four different implementations of Rwlock:
|
||||
// - On Windows (but not Win 7), Linux, Android, FreeBSD, OpenBSD, DragonFly,
|
||||
// Fuchsia, WASM, Hermit, and Motor OSs, it relies on rwlock/futex.rs, which has
|
||||
// a max reader of 1 << 30 - 2 (or 1073741822). A "too many active reader" error
|
||||
// is displayed after it exceeds the max number of readers.
|
||||
// - On Unix, Win 7, Fortranix (target env of sgx), Xous, and TeeOS, it leans
|
||||
// on rwlock/queue.rs, which uses a linked list under the hood stored on the stack
|
||||
// to hold a queue of waiters. Assuming no stack overflow, the max number of readers
|
||||
// that can be queued up at one time is limited to usize::MAX - (1 << 4) as the first
|
||||
// four bits are reserved for LOCKED, QUEUED, QUEUE_LOCKED, and DOWNGRADED flags. Any
|
||||
// pending readers after that max count, parks the thread and tries to acquire a read lock
|
||||
// again when the thread wakes up.
|
||||
// - On SolidASP3, it leans on rwlock/solid.rs, which utilizes rwl_loc_rdl, so the max
|
||||
// number of readers depends on the internal implementation of rwl_loc_rdl.
|
||||
// - Every other platforms utilizes rwlock/no_threads.rs, which has a max reader of
|
||||
// isize::MAX. An arithmetic overflow error occurs if it exceeds the max reader count.
|
||||
#[test]
|
||||
fn test_rwlock_max_readers() {
|
||||
let mut read_lock_ctr: u32 = 0;
|
||||
let rwlock: RwLock<i32> = RwLock::new(0);
|
||||
|
||||
const MAX_READERS: u32 = cfg_select! {
|
||||
miri => 100,
|
||||
any(
|
||||
all(target_os = "windows", not(target_vendor = "win7")),
|
||||
target_os = "linux",
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "fuchsia",
|
||||
all(target_family = "wasm", target_feature = "atomics"),
|
||||
target_os = "hermit",
|
||||
target_os = "motor",
|
||||
) => {
|
||||
(1 << 30) - 2
|
||||
},
|
||||
any(
|
||||
target_family = "unix",
|
||||
all(target_os = "windows", target_vendor = "win7"),
|
||||
all(target_vendor = "fortanix", target_env = "sgx"),
|
||||
target_os = "xous",
|
||||
target_os = "teeos",
|
||||
) => {
|
||||
u32::MAX
|
||||
},
|
||||
target_os = "solid_asp3" => {
|
||||
(1 << 30)
|
||||
},
|
||||
_ => {
|
||||
u32::MAX
|
||||
}
|
||||
};
|
||||
|
||||
while read_lock_ctr < MAX_READERS {
|
||||
let lock = rwlock.read();
|
||||
mem::forget(lock);
|
||||
read_lock_ctr += 1;
|
||||
}
|
||||
|
||||
assert_eq!(read_lock_ctr, MAX_READERS);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user