From 9a92efd50d58043c0af866b92ac907b37c108f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= Date: Wed, 26 Jan 2022 15:37:33 -0500 Subject: [PATCH] Simplify using lock_arc The future returned by lock_arc would already resolve to a MutexGuardArc that kept the Arc alive. Unfortunately, sometimes one needs to store the future itself, not the MutexGuardArc and the future had a reference to the Arc. With this patch, the future itself also has a Arc. --- src/mutex.rs | 17 +++++++++++------ tests/mutex.rs | 10 +++++++++- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/mutex.rs b/src/mutex.rs index adf669d..e5d67e2 100644 --- a/src/mutex.rs +++ b/src/mutex.rs @@ -1,5 +1,6 @@ use std::cell::UnsafeCell; use std::fmt; +use std::future::Future; use std::ops::{Deref, DerefMut}; use std::process; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -263,6 +264,14 @@ impl Mutex { } impl Mutex { + async fn lock_arc_impl(self: Arc) -> MutexGuardArc { + if let Some(guard) = self.try_lock_arc() { + return guard; + } + self.acquire_slow().await; + MutexGuardArc(self) + } + /// Acquires the mutex and clones a reference to it. /// /// Returns an owned guard that releases the mutex when dropped. @@ -280,12 +289,8 @@ impl Mutex { /// # }) /// ``` #[inline] - pub async fn lock_arc(self: &Arc) -> MutexGuardArc { - if let Some(guard) = self.try_lock_arc() { - return guard; - } - self.acquire_slow().await; - MutexGuardArc(self.clone()) + pub fn lock_arc(self: &Arc) -> impl Future> { + self.clone().lock_arc_impl() } /// Attempts to acquire the mutex and clone a reference to it. diff --git a/tests/mutex.rs b/tests/mutex.rs index d1fa94b..0d3520b 100644 --- a/tests/mutex.rs +++ b/tests/mutex.rs @@ -1,4 +1,3 @@ -#[cfg(not(target_arch = "wasm32"))] use std::sync::Arc; #[cfg(not(target_arch = "wasm32"))] use std::thread; @@ -76,3 +75,12 @@ fn contention() { assert_eq!(num_tasks, *lock); }); } + +#[test] +fn lifetime() { + // Show that the future keeps the mutex alive. + let _fut = { + let mutex = Arc::new(Mutex::new(0i32)); + mutex.lock_arc() + }; +}