Struct RwMutex

Source
pub struct RwMutex<T: ?Sized> { /* private fields */ }
Expand description

A mutex that provides data access to either one writer or many readers.

§Overview

This mutex allows for multiple readers, or at most one writer to access at any point in time. The writer of this mutex has exclusive access to modify the underlying data, while the readers are allowed shared and read-only access.

The writing and reading portions cannot be active simultaneously, when one portion is in progress, the other portion will sleep. This is suitable for scenarios where the mutex is expected to be held for a period of time, which can avoid wasting CPU resources.

This implementation provides the upgradeable read mutex (upread mutex). The upread mutex can be upgraded to write mutex atomically, useful in scenarios where a decision to write is made after reading.

The type parameter T represents the data that this mutex is protecting. It is necessary for T to satisfy [Send] to be shared across tasks and [Sync] to permit concurrent access via readers. The [Deref] method (and [DerefMut] for the writer) is implemented for the RAII guards returned by the locking methods, which allows for the access to the protected data while the mutex is held.

§Usage

The mutex can be used in scenarios where data needs to be read frequently but written to occasionally.

Use upread mutex in scenarios where related checking is performed before modification to effectively avoid deadlocks and improve efficiency.

§Safety

Avoid using RwMutex in an interrupt context, as it may result in sleeping and never being awakened.

§Examples

use ostd::sync::RwMutex;

let mutex = RwMutex::new(5)

// many read mutexes can be held at once
{
    let r1 = mutex.read();
    let r2 = mutex.read();
    assert_eq!(*r1, 5);
    assert_eq!(*r2, 5);
     
    // Upgradeable read mutex can share access to data with read mutexes
    let r3 = mutex.upread();
    assert_eq!(*r3, 5);
    drop(r1);
    drop(r2);
    // read mutexes are dropped at this point

    // An upread mutex can only be upgraded successfully after all the
    // read mutexes are released, otherwise it will spin-wait.
    let mut w1 = r3.upgrade();
    *w1 += 1;
    assert_eq!(*w1, 6);
}   // upread mutex are dropped at this point

{   
    // Only one write mutex can be held at a time
    let mut w2 = mutex.write();
    *w2 += 1;
    assert_eq!(*w2, 7);
}   // write mutex is dropped at this point

Implementations§

Source§

impl<T> RwMutex<T>

Source

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

Creates a new read-write mutex with an initial value.

Source§

impl<T: ?Sized> RwMutex<T>

Source

pub fn read(&self) -> RwMutexReadGuard<'_, T>

Acquires a read mutex and sleep until it can be acquired.

The calling thread will sleep until there are no writers or upgrading upreaders present. The implementation of WaitQueue guarantees the order in which other concurrent readers or writers waiting simultaneously will acquire the mutex.

Source

pub fn write(&self) -> RwMutexWriteGuard<'_, T>

Acquires a write mutex and sleep until it can be acquired.

The calling thread will sleep until there are no writers, upreaders, or readers present. The implementation of WaitQueue guarantees the order in which other concurrent readers or writers waiting simultaneously will acquire the mutex.

Source

pub fn upread(&self) -> RwMutexUpgradeableGuard<'_, T>

Acquires a upread mutex and sleep until it can be acquired.

The calling thread will sleep until there are no writers or upreaders present. The implementation of WaitQueue guarantees the order in which other concurrent readers or writers waiting simultaneously will acquire the mutex.

Upreader will not block new readers until it tries to upgrade. Upreader and reader do not differ before invoking the upgread method. However, only one upreader can exist at any time to avoid deadlock in the upgread method.

Source

pub fn try_read(&self) -> Option<RwMutexReadGuard<'_, T>>

Attempts to acquire a read mutex.

This function will never sleep and will return immediately.

Source

pub fn try_write(&self) -> Option<RwMutexWriteGuard<'_, T>>

Attempts to acquire a write mutex.

This function will never sleep and will return immediately.

Source

pub fn try_upread(&self) -> Option<RwMutexUpgradeableGuard<'_, T>>

Attempts to acquire a upread mutex.

This function will never sleep and will return immediately.

Source

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

Returns a mutable reference to the underlying data.

This method is zero-cost: By holding a mutable reference to the lock, the compiler has already statically guaranteed that access to the data is exclusive.

Trait Implementations§

Source§

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

Source§

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

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

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

Because there can be more than one readers to get the T’s immutable ref, so T must be Sync to guarantee the sharing safety.

Source§

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

Auto Trait Implementations§

§

impl<T> !Freeze for RwMutex<T>

§

impl<T> !RefUnwindSafe for RwMutex<T>

§

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

§

impl<T> !UnwindSafe for RwMutex<T>

Blanket Implementations§

§

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

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

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

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

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

§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

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

§

fn into(self) -> U

Calls U::from(self).

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

Source§

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

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Pointee for T

Source§

type Metadata = ()

The metadata type for pointers and references to this type.
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
§

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

§

type Error = Infallible

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

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

Performs the conversion.
§

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

§

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

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

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

Performs the conversion.