Skip to content

Commit 48a5b62

Browse files
committed
Fix semaphore lifetime issue as well
1 parent 1b63cc6 commit 48a5b62

File tree

2 files changed

+27
-13
lines changed

2 files changed

+27
-13
lines changed

src/semaphore.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::future::Future;
12
use std::sync::atomic::{AtomicUsize, Ordering};
23
use std::sync::Arc;
34

@@ -135,6 +136,21 @@ impl Semaphore {
135136
}
136137
}
137138

139+
async fn acquire_arc_impl(self: Arc<Self>) -> SemaphoreGuardArc {
140+
let mut listener = None;
141+
142+
loop {
143+
if let Some(guard) = self.try_acquire_arc() {
144+
return guard;
145+
}
146+
147+
match listener.take() {
148+
None => listener = Some(self.event.listen()),
149+
Some(l) => l.await,
150+
}
151+
}
152+
}
153+
138154
/// Waits for an owned permit for a concurrent operation.
139155
///
140156
/// Returns a guard that releases the permit when dropped.
@@ -150,19 +166,8 @@ impl Semaphore {
150166
/// let guard = s.acquire_arc().await;
151167
/// # });
152168
/// ```
153-
pub async fn acquire_arc(self: &Arc<Self>) -> SemaphoreGuardArc {
154-
let mut listener = None;
155-
156-
loop {
157-
if let Some(guard) = self.try_acquire_arc() {
158-
return guard;
159-
}
160-
161-
match listener.take() {
162-
None => listener = Some(self.event.listen()),
163-
Some(l) => l.await,
164-
}
165-
}
169+
pub fn acquire_arc(self: &Arc<Self>) -> impl Future<Output = SemaphoreGuardArc> {
170+
self.clone().acquire_arc_impl()
166171
}
167172
}
168173

tests/semaphore.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,12 @@ fn multi_resource() {
8181
rx1.recv().unwrap();
8282
});
8383
}
84+
85+
#[test]
86+
fn lifetime() {
87+
// Show that the future keeps the semaphore alive.
88+
let _fut = {
89+
let mutex = Arc::new(Semaphore::new(2));
90+
mutex.acquire_arc()
91+
};
92+
}

0 commit comments

Comments
 (0)