mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-23 00:00:10 +02:00
sync: add Mutex::blocking_lock_owned (#5130)
This commit is contained in:
@@ -418,6 +418,62 @@ impl<T: ?Sized> Mutex<T> {
|
||||
crate::future::block_on(self.lock())
|
||||
}
|
||||
|
||||
/// 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);
|
||||
/// }
|
||||
///
|
||||
/// ```
|
||||
#[track_caller]
|
||||
#[cfg(feature = "sync")]
|
||||
pub fn blocking_lock_owned(self: Arc<Self>) -> OwnedMutexGuard<T> {
|
||||
crate::future::block_on(self.lock_owned())
|
||||
}
|
||||
|
||||
/// 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`].
|
||||
|
||||
Reference in New Issue
Block a user