Skip to main content

RwLock

Struct RwLock 

Source
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>

Source

pub const fn new(value: T) -> Self

An unlocked lock holding value.

Source

pub const fn const_new(value: T) -> Self

An unlocked lock holding value, usable in a static.

Source

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.)

Source

pub const fn const_with_max_readers(value: T, max_reads: u32) -> Self

with_max_readers, usable in a static.

§Panics

As for with_max_readers.

Source

pub fn into_inner(self) -> T

Consumes the lock and returns its value.

Source§

impl<T: ?Sized> RwLock<T>

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn read_owned(self: Arc<Self>) -> ReadOwned<T> ⓘ

read through an Arc, so the guard can outlive the borrow.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn upgradable_read(&self) -> UpgradableRead<'_, T> ⓘ

Waits for the upgradable read. It makes the progress read does.

Source

pub fn get_mut(&mut self) -> &mut T

The value, borrowed mutably; &mut self proves no guard exists.

Trait Implementations§

Source§

impl<T: ?Sized + Debug> Debug for RwLock<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Default> Default for RwLock<T>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<T> From<T> for RwLock<T>

Source§

fn from(value: T) -> Self

Converts to this type from the input type.
Source§

impl<T: ?Sized + Send> Send for RwLock<T>

Source§

impl<T: ?Sized + Send + Sync> Sync for RwLock<T>

Auto Trait Implementations§

§

impl<T> !Freeze for RwLock<T>

§

impl<T> !RefUnwindSafe for RwLock<T>

§

impl<T> !UnwindSafe for RwLock<T>

§

impl<T> Unpin for RwLock<T>
where T: Unpin + ?Sized,

§

impl<T> UnsafeUnpin for RwLock<T>
where T: UnsafeUnpin + ?Sized,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<!> for T

Source§

fn from(t: !) -> T

Converts to this type from the input type.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> MaybeSend for T
where T: Send + ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.