Skip to content

Commit

Permalink
Fix semaphore lifetime issue as well
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Feb 19, 2022
1 parent 1b63cc6 commit 3d2c193
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 13 deletions.
31 changes: 18 additions & 13 deletions src/semaphore.rs
@@ -1,3 +1,4 @@
use std::future::Future;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;

Expand Down Expand Up @@ -135,6 +136,21 @@ impl Semaphore {
}
}

async fn acquire_arc_impl(self: Arc<Self>) -> 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.
Expand All @@ -150,19 +166,8 @@ impl Semaphore {
/// let guard = s.acquire_arc().await;
/// # });
/// ```
pub async fn acquire_arc(self: &Arc<Self>) -> 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<Self>) -> impl Future<Output = SemaphoreGuardArc> {
self.clone().acquire_arc_impl()
}
}

Expand Down
9 changes: 9 additions & 0 deletions tests/semaphore.rs
Expand Up @@ -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()
};
}

0 comments on commit 3d2c193

Please sign in to comment.