pub struct Mutex<T> { /* private fields */ }Expand description
An awaitable, single-threaded mutex. Only a single reference to the contents of the mutex can exist at any time.
All accesses are parked and waked in FIFO order.
Implementations§
Source§impl<T> Mutex<T>
impl<T> Mutex<T>
Sourcepub fn new(value: T) -> Self
pub fn new(value: T) -> Self
Creates a new mutex storing the given value.
use wb_async_utils::mutex::*;
let m = Mutex::new(5);
assert_eq!(5, m.into_inner());Sourcepub fn into_inner(self) -> T
pub fn into_inner(self) -> T
Consumes the mutex and returns the wrapped value.
use wb_async_utils::mutex::*;
let m = Mutex::new(5);
assert_eq!(5, m.into_inner());Sourcepub async fn read(&self) -> ReadGuard<'_, T>
pub async fn read(&self) -> ReadGuard<'_, T>
Gives read access to the wrapped value, waiting if necessary.
use wb_async_utils::mutex::*;
use core::ops::Deref;
use core::time::Duration;
let m = Mutex::new(0);
pollster::block_on(async {
let handle = m.read().await;
assert_eq!(0, *handle.deref());
});Sourcepub fn try_read(&self) -> Option<ReadGuard<'_, T>>
pub fn try_read(&self) -> Option<ReadGuard<'_, T>>
Gives read access if doing so is possible without waiting, returns None otherwise.
use wb_async_utils::mutex::*;
use core::ops::Deref;
use core::time::Duration;
use smol::{block_on, Timer};
let m = Mutex::new(0);
assert_eq!(&0, m.try_read().unwrap().deref());
block_on(futures::future::join(async {
let handle = m.read().await;
Timer::after(Duration::from_millis(50)).await;
}, async {
assert!(m.try_read().is_none());
}));Sourcepub async fn write(&self) -> WriteGuard<'_, T>
pub async fn write(&self) -> WriteGuard<'_, T>
Gives write access to the wrapped value, waiting if necessary.
use wb_async_utils::mutex::*;
use core::ops::{Deref, DerefMut};
use core::time::Duration;
use smol::{block_on, Timer};
let m = Mutex::new(0);
block_on(futures::future::join(async {
let mut handle = m.write().await;
// Simulate doing some work.
Timer::after(Duration::from_millis(50)).await;
assert_eq!(0, *handle.deref());
*handle.deref_mut() = 1;
}, async {
// This future is "faster", but has to wait for the "work" performed by the first one.
let mut handle = m.write().await;
assert_eq!(1, *handle.deref());
}));Sourcepub fn try_write(&self) -> Option<WriteGuard<'_, T>>
pub fn try_write(&self) -> Option<WriteGuard<'_, T>>
Gives write access if doing so is possible without waiting, returns None otherwise.
use wb_async_utils::mutex::*;
use core::ops::Deref;
use core::time::Duration;
use smol::{block_on, Timer};
let m = Mutex::new(0);
assert_eq!(&0, m.try_write().unwrap().deref());
block_on(futures::future::join(async {
let handle = m.write().await;
Timer::after(Duration::from_millis(50)).await;
}, async {
assert!(m.try_write().is_none());
}));Sourcepub async fn set(&self, to: T)
pub async fn set(&self, to: T)
Sets the wrapped value.
Needs to .await write access internally.
use wb_async_utils::mutex::*;
use core::ops::Deref;
let m = Mutex::new(0);
pollster::block_on(async {
m.set(1).await;
assert_eq!(1, *m.read().await.deref());
});Sourcepub async fn replace(&self, to: T) -> T
pub async fn replace(&self, to: T) -> T
Replaces the wrapped value, and returns the old one.
Needs to .await read access internally.
use wb_async_utils::mutex::*;
use core::ops::Deref;
let m = Mutex::new(0);
pollster::block_on(async {
assert_eq!(0, m.replace(1).await);
assert_eq!(1, *m.read().await.deref());
});Sourcepub async fn update(&self, with: impl FnOnce(&T) -> T)
pub async fn update(&self, with: impl FnOnce(&T) -> T)
Updates the wrapped value with the given function.
Needs to .await read access internally.
use wb_async_utils::mutex::*;
use core::ops::Deref;
let m = Mutex::new(0);
pollster::block_on(async {
m.update(|x| x + 1).await;
assert_eq!(1, *m.read().await.deref());
});Sourcepub async fn fallible_update<E>(
&self,
with: impl FnOnce(&T) -> Result<T, E>,
) -> Result<(), E>
pub async fn fallible_update<E>( &self, with: impl FnOnce(&T) -> Result<T, E>, ) -> Result<(), E>
Updates the wrapped value with the successful result of the given function, or propagates the error of the function.
Needs to .await read access internally.
use wb_async_utils::mutex::*;
use core::ops::Deref;
let m = Mutex::new(0);
pollster::block_on(async {
assert_eq!(Ok(()), m.fallible_update(|x| Ok::<u8, i8>(x + 1)).await);
assert_eq!(1, *m.read().await.deref());
assert_eq!(Err(-17), m.fallible_update(|_| Err(-17)).await);
assert_eq!(1, *m.read().await.deref());
});Sourcepub async fn mutate(&self, with: impl FnOnce(&mut T))
pub async fn mutate(&self, with: impl FnOnce(&mut T))
Mutates the wrapped value with the given function.
Needs to .await read access internally.
use wb_async_utils::mutex::*;
use core::ops::Deref;
let m = Mutex::new(0);
pollster::block_on(async {
m.mutate(|x| *x += 1).await;
assert_eq!(1, *m.read().await.deref());
});Sourcepub async fn fallible_mutate<E>(
&self,
with: impl FnOnce(&mut T) -> Result<(), E>,
) -> Result<(), E>
pub async fn fallible_mutate<E>( &self, with: impl FnOnce(&mut T) -> Result<(), E>, ) -> Result<(), E>
Mutates the wrapped value with the given fallible function, propagates its error if any.
Needs to .await read access internally.
use wb_async_utils::mutex::*;
use core::ops::Deref;
let m = Mutex::new(0);
pollster::block_on(async {
assert_eq!(Ok(()), m.fallible_mutate(|x| {
*x +=1 ;
Ok::<(), i8>(())
}).await);
assert_eq!(1, *m.read().await.deref());
assert_eq!(Err(-17), m.fallible_mutate(|_| Err(-17)).await);
assert_eq!(1, *m.read().await.deref());
});Trait Implementations§
Auto Trait Implementations§
impl<T> !Freeze for Mutex<T>
impl<T> !RefUnwindSafe for Mutex<T>
impl<T> !Sync for Mutex<T>
impl<T> Send for Mutex<T>where
FairlyUnsafeCell<T>: Send,
impl<T> Unpin for Mutex<T>where
FairlyUnsafeCell<T>: Unpin,
impl<T> UnsafeUnpin for Mutex<T>where
FairlyUnsafeCell<T>: UnsafeUnpin,
impl<T> UnwindSafe for Mutex<T>where
FairlyUnsafeCell<T>: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more