Struct futures_locks::Mutex
source · pub struct Mutex<T: ?Sized> { /* private fields */ }
Expand description
A Futures-aware Mutex.
std::sync::Mutex
cannot be used in an asynchronous environment like Tokio,
because a mutex acquisition can block an entire reactor. This class can be
used instead. It functions much like std::sync::Mutex
. Unlike that
class, it also has a builtin Arc
, making it accessible from multiple
threads. It’s also safe to clone
. Also unlike std::sync::Mutex
, this
class does not detect lock poisoning.
Examples
let mtx = Mutex::<u32>::new(0);
let fut = mtx.lock().map(|mut guard| { *guard += 5; });
block_on(fut);
assert_eq!(mtx.try_unwrap().unwrap(), 5);
Implementations§
source§impl<T: ?Sized> Mutex<T>
impl<T: ?Sized> Mutex<T>
sourcepub fn get_mut(&mut self) -> Option<&mut T>
pub fn get_mut(&mut self) -> Option<&mut T>
Returns a reference to the underlying data, if there are no other
clones of the Mutex
.
Since this call borrows the Mutex
mutably, no actual locking takes
place – the mutable borrow statically guarantees no locks exist.
However, if the Mutex
has already been cloned, then None
will be
returned instead.
Examples
let mut mtx = Mutex::<u32>::new(0);
*mtx.get_mut().unwrap() += 5;
assert_eq!(mtx.try_unwrap().unwrap(), 5);
sourcepub fn lock(&self) -> MutexFut<T> ⓘ
pub fn lock(&self) -> MutexFut<T> ⓘ
Acquires a Mutex
, blocking the task in the meantime. When the
returned Future
is ready, this task will have sole access to the
protected data.
sourcepub fn try_lock(&self) -> Result<MutexGuard<T>, TryLockError>
pub fn try_lock(&self) -> Result<MutexGuard<T>, TryLockError>
Attempts to acquire the lock.
If the operation would block, returns Err
instead. Otherwise, returns
a guard (not a Future
).
Examples
let mut mtx = Mutex::<u32>::new(0);
match mtx.try_lock() {
Ok(mut guard) => *guard += 5,
Err(_) => println!("Better luck next time!")
};
source§impl<T: 'static + ?Sized> Mutex<T>
impl<T: 'static + ?Sized> Mutex<T>
sourcepub fn with<B, F, R>(&self, f: F) -> impl Future<Output = R>where
F: FnOnce(MutexGuard<T>) -> B + Send + 'static,
B: Future<Output = R> + Send + 'static,
R: Send + 'static,
T: Send,
Available on crate feature tokio
only.
pub fn with<B, F, R>(&self, f: F) -> impl Future<Output = R>where
F: FnOnce(MutexGuard<T>) -> B + Send + 'static,
B: Future<Output = R> + Send + 'static,
R: Send + 'static,
T: Send,
tokio
only.Acquires a Mutex
and performs a computation on its guarded value in a
separate task. Returns a Future
containing the result of the
computation.
When using Tokio, this method will often hold the Mutex
for less time
than chaining a computation to lock
. The reason is
that Tokio polls all tasks promptly upon notification. However, Tokio
does not guarantee that it will poll all futures promptly when their
owning task gets notified. So it’s best to hold Mutex
es within their
own tasks, lest their continuations get blocked by slow stacked
combinators.
Examples
let mtx = Mutex::<u32>::new(0);
let mut rt = Runtime::new().unwrap();
rt.block_on(async {
mtx.with(|mut guard| {
*guard += 5;
ready::<()>(())
}).await
});
assert_eq!(mtx.try_unwrap().unwrap(), 5);
sourcepub fn with_local<B, F, R>(&self, f: F) -> impl Future<Output = R>where
F: FnOnce(MutexGuard<T>) -> B + 'static,
B: Future<Output = R> + 'static + Unpin,
R: 'static,
Available on crate feature tokio
only.
pub fn with_local<B, F, R>(&self, f: F) -> impl Future<Output = R>where
F: FnOnce(MutexGuard<T>) -> B + 'static,
B: Future<Output = R> + 'static + Unpin,
R: 'static,
tokio
only.Like with
but for Futures that aren’t Send
.
Spawns a new task on a single-threaded Runtime to complete the Future.
Examples
// Note: Rc is not `Send`
let mtx = Mutex::<Rc<u32>>::new(Rc::new(0));
let mut rt = Runtime::new().unwrap();
rt.block_on(async {
mtx.with_local(|mut guard| {
*Rc::get_mut(&mut *guard).unwrap() += 5;
ready(())
}).await
});
assert_eq!(*mtx.try_unwrap().unwrap(), 5);