//! Future types //! use futures_core::ready; use pin_project::{pin_project, pinned_drop}; use std::sync::Arc; use std::{ future::Future, pin::Pin, task::{Context, Poll}, }; use tokio_sync::semaphore::Semaphore; /// Future for the `ConcurrencyLimit` service. #[pin_project(PinnedDrop)] #[derive(Debug)] pub struct ResponseFuture { #[pin] inner: T, semaphore: Arc, } impl ResponseFuture { pub(crate) fn new(inner: T, semaphore: Arc) -> ResponseFuture { ResponseFuture { inner, semaphore } } } impl Future for ResponseFuture where F: Future>, { type Output = Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Poll::Ready(ready!(self.project().inner.poll(cx))) } } #[pinned_drop] impl PinnedDrop for ResponseFuture { fn drop(self: Pin<&mut Self>) { self.project().semaphore.add_permits(1); } }