pub struct RwLock<T: ?Sized> { /* private fields */ }Expand description
A reader-writer lock whose waits are futures.
Uncontended, a read or write lock and its release are one atomic
read-modify-write each and allocate nothing. Under contention a caller
takes the lock whenever it is free to it, even past queued waiters, so
a release never waits for a suspended task; a waiter passed over
MAX_BYPASS times is handed the lock next, and
nobody gets in ahead of it meanwhile, so neither readers nor writers
starve.
upgradable_read takes a read that can later
become the write without letting a writer in between. One upgradable
read exists at a time; it shares the lock with plain readers, and plain
read guards cannot upgrade. A write guard becomes a read guard, with no
writer in between, through
RwLockWriteGuard::downgrade.
use nuclei::sync::RwLock;
let lock = RwLock::new(5);
let a = lock.try_read().expect("free");
let b = lock.try_read().expect("readers share");
assert!(lock.try_write().is_err());
drop((a, b));
*lock.try_write().expect("free again") += 1;
assert_eq!(lock.into_inner(), 6);Implementations§
Source§impl<T> RwLock<T>
impl<T> RwLock<T>
Sourcepub const fn with_max_readers(value: T, max_reads: u32) -> Self
pub const fn with_max_readers(value: T, max_reads: u32) -> Self
An unlocked lock holding value that admits at most max_reads
readers at once: a reader that finds them all inside waits for
one to leave, as one held back by a writer does.
§Panics
When max_reads is 0 or is bigger than u32::MAX >> 3. (A
target whose word is narrower than 64 bits caps it lower, at the
readers its state word can count: 2^23 - 1 on 32 bits.)
Sourcepub const fn const_with_max_readers(value: T, max_reads: u32) -> Self
pub const fn const_with_max_readers(value: T, max_reads: u32) -> Self
Sourcepub fn into_inner(self) -> T
pub fn into_inner(self) -> T
Consumes the lock and returns its value.
Source§impl<T: ?Sized> RwLock<T>
impl<T: ?Sized> RwLock<T>
Sourcepub fn try_read(&self) -> Result<RwLockReadGuard<'_, T>, TryLockError>
pub fn try_read(&self) -> Result<RwLockReadGuard<'_, T>, TryLockError>
Shares the lock if no writer holds it, no upgrade is under way, the readers have room and no handoff is owed.
§Errors
TryLockError when any of those fails.
Sourcepub fn try_read_owned(
self: Arc<Self>,
) -> Result<OwnedRwLockReadGuard<T>, TryLockError>
pub fn try_read_owned( self: Arc<Self>, ) -> Result<OwnedRwLockReadGuard<T>, TryLockError>
try_read through an Arc, so the guard can
outlive the borrow.
§Errors
TryLockError when the lock cannot be shared now.
Sourcepub fn try_write(&self) -> Result<RwLockWriteGuard<'_, T>, TryLockError>
pub fn try_write(&self) -> Result<RwLockWriteGuard<'_, T>, TryLockError>
Takes the lock alone if nobody holds it and no handoff is owed.
§Errors
TryLockError when any reader or writer holds the lock, or a
waiter is owed it.
Sourcepub fn try_write_owned(
self: Arc<Self>,
) -> Result<OwnedRwLockWriteGuard<T>, TryLockError>
pub fn try_write_owned( self: Arc<Self>, ) -> Result<OwnedRwLockWriteGuard<T>, TryLockError>
try_write through an Arc, so the guard can
outlive the borrow.
§Errors
TryLockError when the lock cannot be taken alone now.
Sourcepub fn try_upgradable_read(&self) -> Option<RwLockUpgradableReadGuard<'_, T>>
pub fn try_upgradable_read(&self) -> Option<RwLockUpgradableReadGuard<'_, T>>
Takes the upgradable read if no writer and no other upgradable read holds the lock and no handoff is owed.
Sourcepub fn read(&self) -> Read<'_, T> ⓘ
pub fn read(&self) -> Read<'_, T> ⓘ
Waits to share the lock. Uncontended, the first poll is one atomic read-modify-write. Contended, it is lock-free, not wait-free: see Progress.
Dropping the future withdraws the wait, and passes on a lock handed to it meanwhile.
Sourcepub fn read_owned(self: Arc<Self>) -> ReadOwned<T> ⓘ
pub fn read_owned(self: Arc<Self>) -> ReadOwned<T> ⓘ
read through an Arc, so the guard can outlive the
borrow.
Sourcepub fn write(&self) -> Write<'_, T> ⓘ
pub fn write(&self) -> Write<'_, T> ⓘ
Waits to hold the lock alone. Uncontended, the first poll is one atomic read-modify-write. Contended, it is lock-free, not wait-free: see Progress.
Dropping the future withdraws the wait, and passes on a lock handed to it meanwhile.
Sourcepub fn write_owned(self: Arc<Self>) -> WriteOwned<T> ⓘ
pub fn write_owned(self: Arc<Self>) -> WriteOwned<T> ⓘ
Waits to hold the lock alone, with a guard that keeps the lock alive itself, so the future and the guard can outlive the borrow that made them: a wait kept across calls, or a guard returned to a caller.
Sourcepub fn blocking_read(&self) -> RwLockReadGuard<'_, T>
pub fn blocking_read(&self) -> RwLockReadGuard<'_, T>
read for a thread that may block: it parks the
calling thread until the lock can be shared. On a nuclei shard (inside one of its tasks) it does not park the thread: it runs a nested block_on, so the shard keeps running its other tasks meanwhile.
Inside another runtime’s task it blocks that task’s executor thread,
so do not: the task that would release may be the one that thread was
running.
§Panics
On wasm32, where no other thread can release, when the lock cannot
be shared at once: the call could never end.
Sourcepub fn blocking_write(&self) -> RwLockWriteGuard<'_, T>
pub fn blocking_write(&self) -> RwLockWriteGuard<'_, T>
write for a thread that may block: see
blocking_read.
§Panics
On wasm32, where no other thread can release, when the lock is held
at all: the call could never end.
Sourcepub fn upgradable_read(&self) -> UpgradableRead<'_, T> ⓘ
pub fn upgradable_read(&self) -> UpgradableRead<'_, T> ⓘ
Waits for the upgradable read. It makes the progress
read does.