From 3d2c1930778e16df3a15b79ca3acb22109452851 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sat, 19 Feb 2022 19:26:11 +0900 Subject: [PATCH 1/2] Fix semaphore lifetime issue as well --- src/semaphore.rs | 31 ++++++++++++++++++------------- tests/semaphore.rs | 9 +++++++++ 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/semaphore.rs b/src/semaphore.rs index 65768d7..094b061 100644 --- a/src/semaphore.rs +++ b/src/semaphore.rs @@ -1,3 +1,4 @@ +use std::future::Future; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; @@ -135,6 +136,21 @@ impl Semaphore { } } + async fn acquire_arc_impl(self: Arc) -> SemaphoreGuardArc { + let mut listener = None; + + loop { + if let Some(guard) = self.try_acquire_arc() { + return guard; + } + + match listener.take() { + None => listener = Some(self.event.listen()), + Some(l) => l.await, + } + } + } + /// Waits for an owned permit for a concurrent operation. /// /// Returns a guard that releases the permit when dropped. @@ -150,19 +166,8 @@ impl Semaphore { /// let guard = s.acquire_arc().await; /// # }); /// ``` - pub async fn acquire_arc(self: &Arc) -> SemaphoreGuardArc { - let mut listener = None; - - loop { - if let Some(guard) = self.try_acquire_arc() { - return guard; - } - - match listener.take() { - None => listener = Some(self.event.listen()), - Some(l) => l.await, - } - } + pub fn acquire_arc(self: &Arc) -> impl Future { + self.clone().acquire_arc_impl() } } diff --git a/tests/semaphore.rs b/tests/semaphore.rs index 8487dcc..2dc42d4 100644 --- a/tests/semaphore.rs +++ b/tests/semaphore.rs @@ -81,3 +81,12 @@ fn multi_resource() { rx1.recv().unwrap(); }); } + +#[test] +fn lifetime() { + // Show that the future keeps the semaphore alive. + let _fut = { + let mutex = Arc::new(Semaphore::new(2)); + mutex.acquire_arc() + }; +} From 8e02f082c2f71d8941d3a045a9fedc48f08fa2c3 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sat, 19 Feb 2022 19:28:16 +0900 Subject: [PATCH 2/2] Release 2.5.0 --- CHANGELOG.md | 4 ++++ Cargo.toml | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 218932b..2ccb983 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# Version 2.5.0 + +- Fix an issue where the future returned by `Mutex::lock_arc`/`Semaphore::acquire_arc` holds a reference to `self`. (#20, #21) + # Version 2.4.0 - Add WASM support. (#14) diff --git a/Cargo.toml b/Cargo.toml index 50f74ea..dcd5c9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,15 +3,13 @@ name = "async-lock" # When publishing a new version: # - Update CHANGELOG.md # - Create "v2.x.y" git tag -version = "2.4.0" +version = "2.5.0" authors = ["Stjepan Glavina "] edition = "2018" rust-version = "1.43" description = "Async synchronization primitives" license = "Apache-2.0 OR MIT" repository = "https://github.com/smol-rs/async-lock" -homepage = "https://github.com/smol-rs/async-lock" -documentation = "https://docs.rs/async-lock" keywords = ["lock", "mutex", "rwlock", "semaphore", "barrier"] categories = ["asynchronous", "concurrency"] exclude = ["/.*"]