@@ -418,6 +418,62 @@ impl<T: ?Sized> Mutex<T> {
418
418
crate :: future:: block_on ( self . lock ( ) )
419
419
}
420
420
421
+ /// Blockingly locks this `Mutex`. When the lock has been acquired, function returns an
422
+ /// [`OwnedMutexGuard`].
423
+ ///
424
+ /// This method is identical to [`Mutex::blocking_lock`], except that the returned
425
+ /// guard references the `Mutex` with an [`Arc`] rather than by borrowing
426
+ /// it. Therefore, the `Mutex` must be wrapped in an `Arc` to call this
427
+ /// method, and the guard will live for the `'static` lifetime, as it keeps
428
+ /// the `Mutex` alive by holding an `Arc`.
429
+ ///
430
+ /// # Panics
431
+ ///
432
+ /// This function panics if called within an asynchronous execution context.
433
+ ///
434
+ /// - If you find yourself in an asynchronous execution context and needing
435
+ /// to call some (synchronous) function which performs one of these
436
+ /// `blocking_` operations, then consider wrapping that call inside
437
+ /// [`spawn_blocking()`][crate::runtime::Handle::spawn_blocking]
438
+ /// (or [`block_in_place()`][crate::task::block_in_place]).
439
+ ///
440
+ /// # Examples
441
+ ///
442
+ /// ```
443
+ /// use std::sync::Arc;
444
+ /// use tokio::sync::Mutex;
445
+ ///
446
+ /// #[tokio::main]
447
+ /// async fn main() {
448
+ /// let mutex = Arc::new(Mutex::new(1));
449
+ /// let lock = mutex.lock().await;
450
+ ///
451
+ /// let mutex1 = Arc::clone(&mutex);
452
+ /// let blocking_task = tokio::task::spawn_blocking(move || {
453
+ /// // This shall block until the `lock` is released.
454
+ /// let mut n = mutex1.blocking_lock_owned();
455
+ /// *n = 2;
456
+ /// });
457
+ ///
458
+ /// assert_eq!(*lock, 1);
459
+ /// // Release the lock.
460
+ /// drop(lock);
461
+ ///
462
+ /// // Await the completion of the blocking task.
463
+ /// blocking_task.await.unwrap();
464
+ ///
465
+ /// // Assert uncontended.
466
+ /// let n = mutex.try_lock().unwrap();
467
+ /// assert_eq!(*n, 2);
468
+ /// }
469
+ ///
470
+ /// ```
471
+ #[ track_caller]
472
+ #[ cfg( feature = "sync" ) ]
473
+ pub fn blocking_lock_owned ( self : Arc < Self > ) -> OwnedMutexGuard < T > {
474
+ crate :: future:: block_on ( self . lock_owned ( ) )
475
+ }
476
+
421
477
/// Locks this mutex, causing the current task to yield until the lock has
422
478
/// been acquired. When the lock has been acquired, this returns an
423
479
/// [`OwnedMutexGuard`].
0 commit comments