tower_limit/concurrency/
future.rs1use super::sync::semaphore::Semaphore;
4use futures_core::ready;
5use pin_project::{pin_project, pinned_drop};
6use std::sync::Arc;
7use std::{
8 future::Future,
9 pin::Pin,
10 task::{Context, Poll},
11};
12
13#[pin_project(PinnedDrop)]
15#[derive(Debug)]
16pub struct ResponseFuture<T> {
17 #[pin]
18 inner: T,
19 semaphore: Arc<Semaphore>,
20}
21
22impl<T> ResponseFuture<T> {
23 pub(crate) fn new(inner: T, semaphore: Arc<Semaphore>) -> ResponseFuture<T> {
24 ResponseFuture { inner, semaphore }
25 }
26}
27
28impl<F, T, E> Future for ResponseFuture<F>
29where
30 F: Future<Output = Result<T, E>>,
31{
32 type Output = Result<T, E>;
33
34 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
35 Poll::Ready(ready!(self.project().inner.poll(cx)))
36 }
37}
38
39#[pinned_drop]
40impl<T> PinnedDrop for ResponseFuture<T> {
41 fn drop(self: Pin<&mut Self>) {
42 self.project().semaphore.add_permits(1);
43 }
44}