pub struct ArcAsyncMutex<T> { /* private fields */ }Expand description
Asynchronous Mutex Wrapper
Provides an encapsulation of asynchronous mutex for protecting shared data in asynchronous environments. Supports safe access and modification of shared data across multiple asynchronous tasks.
§Features
- Asynchronously acquires locks, does not block threads
- Supports trying to acquire locks (non-blocking)
- Thread-safe, supports multi-threaded sharing
- Automatic lock management through RAII ensures proper lock release
- Implements
DerefandAsRefto expose the underlyingtokio::sync::MutexAPI when guard-based access is needed
§Usage Example
use qubit_lock::lock::{ArcAsyncMutex, AsyncLock};
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
rt.block_on(async {
let counter = ArcAsyncMutex::new(0);
// Asynchronously modify data
counter.write(|c| {
*c += 1;
println!("Counter: {}", *c);
}).await;
// Try to acquire lock
if let Ok(value) = counter.try_read(|c| *c) {
println!("Current value: {}", value);
}
});Implementations§
Methods from Deref<Target = AsyncMutex<T>>§
Sourcepub async fn lock(&self) -> MutexGuard<'_, T>
pub async fn lock(&self) -> MutexGuard<'_, T>
Locks this mutex, causing the current task to yield until the lock has
been acquired. When the lock has been acquired, function returns a
MutexGuard.
If the mutex is available to be acquired immediately, then this call will typically not yield to the runtime. However, this is not guaranteed under all circumstances.
§Cancel safety
This method uses a queue to fairly distribute locks in the order they
were requested. Cancelling a call to lock makes you lose your place in
the queue.
§Examples
use tokio::sync::Mutex;
let mutex = Mutex::new(1);
let mut n = mutex.lock().await;
*n = 2;Sourcepub fn blocking_lock(&self) -> MutexGuard<'_, T>
pub fn blocking_lock(&self) -> MutexGuard<'_, T>
Blockingly locks this Mutex. When the lock has been acquired, function returns a
MutexGuard.
This method is intended for use cases where you need to use this mutex in asynchronous code as well as in synchronous code.
§Panics
This function panics if called within an asynchronous execution context.
- If you find yourself in an asynchronous execution context and needing
to call some (synchronous) function which performs one of these
blocking_operations, then consider wrapping that call inside [spawn_blocking()][crate::runtime::Handle::spawn_blocking] (or [block_in_place()][crate::task::block_in_place]).
§Examples
use std::sync::Arc;
use tokio::sync::Mutex;
#[tokio::main]
async fn main() {
let mutex = Arc::new(Mutex::new(1));
let lock = mutex.lock().await;
let mutex1 = Arc::clone(&mutex);
let blocking_task = tokio::task::spawn_blocking(move || {
// This shall block until the `lock` is released.
let mut n = mutex1.blocking_lock();
*n = 2;
});
assert_eq!(*lock, 1);
// Release the lock.
drop(lock);
// Await the completion of the blocking task.
blocking_task.await.unwrap();
// Assert uncontended.
let n = mutex.try_lock().unwrap();
assert_eq!(*n, 2);
}Sourcepub fn blocking_lock_owned(self: Arc<Mutex<T>>) -> OwnedMutexGuard<T>
pub fn blocking_lock_owned(self: Arc<Mutex<T>>) -> OwnedMutexGuard<T>
Blockingly locks this Mutex. When the lock has been acquired, function returns an
OwnedMutexGuard.
This method is identical to Mutex::blocking_lock, except that the returned
guard references the Mutex with an Arc rather than by borrowing
it. Therefore, the Mutex must be wrapped in an Arc to call this
method, and the guard will live for the 'static lifetime, as it keeps
the Mutex alive by holding an Arc.
§Panics
This function panics if called within an asynchronous execution context.
- If you find yourself in an asynchronous execution context and needing
to call some (synchronous) function which performs one of these
blocking_operations, then consider wrapping that call inside [spawn_blocking()][crate::runtime::Handle::spawn_blocking] (or [block_in_place()][crate::task::block_in_place]).
§Examples
use std::sync::Arc;
use tokio::sync::Mutex;
#[tokio::main]
async fn main() {
let mutex = Arc::new(Mutex::new(1));
let lock = mutex.lock().await;
let mutex1 = Arc::clone(&mutex);
let blocking_task = tokio::task::spawn_blocking(move || {
// This shall block until the `lock` is released.
let mut n = mutex1.blocking_lock_owned();
*n = 2;
});
assert_eq!(*lock, 1);
// Release the lock.
drop(lock);
// Await the completion of the blocking task.
blocking_task.await.unwrap();
// Assert uncontended.
let n = mutex.try_lock().unwrap();
assert_eq!(*n, 2);
}Sourcepub async fn lock_owned(self: Arc<Mutex<T>>) -> OwnedMutexGuard<T>
pub async fn lock_owned(self: Arc<Mutex<T>>) -> OwnedMutexGuard<T>
Locks this mutex, causing the current task to yield until the lock has
been acquired. When the lock has been acquired, this returns an
OwnedMutexGuard.
If the mutex is available to be acquired immediately, then this call will typically not yield to the runtime. However, this is not guaranteed under all circumstances.
This method is identical to Mutex::lock, except that the returned
guard references the Mutex with an Arc rather than by borrowing
it. Therefore, the Mutex must be wrapped in an Arc to call this
method, and the guard will live for the 'static lifetime, as it keeps
the Mutex alive by holding an Arc.
§Cancel safety
This method uses a queue to fairly distribute locks in the order they
were requested. Cancelling a call to lock_owned makes you lose your
place in the queue.
§Examples
use tokio::sync::Mutex;
use std::sync::Arc;
let mutex = Arc::new(Mutex::new(1));
let mut n = mutex.clone().lock_owned().await;
*n = 2;Sourcepub fn try_lock(&self) -> Result<MutexGuard<'_, T>, TryLockError>
pub fn try_lock(&self) -> Result<MutexGuard<'_, T>, TryLockError>
Attempts to acquire the lock, and returns TryLockError if the
lock is currently held somewhere else.
§Examples
use tokio::sync::Mutex;
let mutex = Mutex::new(1);
let n = mutex.try_lock()?;
assert_eq!(*n, 1);Sourcepub fn try_lock_owned(
self: Arc<Mutex<T>>,
) -> Result<OwnedMutexGuard<T>, TryLockError>
pub fn try_lock_owned( self: Arc<Mutex<T>>, ) -> Result<OwnedMutexGuard<T>, TryLockError>
Attempts to acquire the lock, and returns TryLockError if the lock
is currently held somewhere else.
This method is identical to Mutex::try_lock, except that the
returned guard references the Mutex with an Arc rather than by
borrowing it. Therefore, the Mutex must be wrapped in an Arc to call
this method, and the guard will live for the 'static lifetime, as it
keeps the Mutex alive by holding an Arc.
§Examples
use tokio::sync::Mutex;
use std::sync::Arc;
let mutex = Arc::new(Mutex::new(1));
let n = mutex.clone().try_lock_owned()?;
assert_eq!(*n, 1);Trait Implementations§
Source§impl<T> AsRef<Mutex<T>> for ArcAsyncMutex<T>
impl<T> AsRef<Mutex<T>> for ArcAsyncMutex<T>
Source§fn as_ref(&self) -> &AsyncMutex<T>
fn as_ref(&self) -> &AsyncMutex<T>
Returns a reference to the underlying Tokio mutex.
This is useful when callers need guard-based APIs such as
AsyncMutex::lock or AsyncMutex::try_lock instead of the
closure-based AsyncLock methods.
Source§impl<T> AsyncLock<T> for ArcAsyncMutex<T>where
T: Send,
impl<T> AsyncLock<T> for ArcAsyncMutex<T>where
T: Send,
Source§fn try_read<R, F>(&self, f: F) -> Result<R, TryLockError>
fn try_read<R, F>(&self, f: F) -> Result<R, TryLockError>
Attempts to acquire the mutex for a read-only operation without waiting.
§Arguments
f- Closure receiving immutable access when the mutex is available.
§Returns
Ok(result) if the mutex was acquired, or
TryLockError::WouldBlock if it was busy.
Source§fn try_write<R, F>(&self, f: F) -> Result<R, TryLockError>
fn try_write<R, F>(&self, f: F) -> Result<R, TryLockError>
Attempts to acquire the mutex for a mutable operation without waiting.
§Arguments
f- Closure receiving mutable access when the mutex is available.
§Returns
Ok(result) if the mutex was acquired, or
TryLockError::WouldBlock if it was busy.
Source§impl<T> Clone for ArcAsyncMutex<T>
impl<T> Clone for ArcAsyncMutex<T>
Source§fn clone(&self) -> Self
fn clone(&self) -> Self
Clones the asynchronous mutex
Creates a new ArcAsyncMutex instance that shares the same
underlying lock with the original instance. This allows
multiple tasks to hold references to the same lock
simultaneously.
§Returns
A new handle sharing the same underlying async mutex and protected value.
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more