From 0aaea29db580a940aa0dfd3ff65979dcc02eddb5 Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Wed, 21 May 2025 13:39:31 +0200 Subject: [PATCH] avoid doubule box --- quinn/src/runtime/tokio.rs | 40 +++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/quinn/src/runtime/tokio.rs b/quinn/src/runtime/tokio.rs index 2d6597a54..b511588f4 100644 --- a/quinn/src/runtime/tokio.rs +++ b/quinn/src/runtime/tokio.rs @@ -56,20 +56,35 @@ struct UdpSocket { } pin_project_lite::pin_project! { - struct UdpSender { - #[pin] - fut: Option> + Send + Sync + 'static>>>, + struct UdpSender { inner: Arc, + make_fut: MakeFut, + #[pin] + fut: Option, } } -impl Debug for UdpSender { +impl Debug for UdpSender { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str("UdpSender") } } -impl super::UdpSender for UdpSender { +impl UdpSender { + fn new(inner: Arc, make_fut: MakeFut) -> Self { + Self { + inner, + fut: None, + make_fut, + } + } +} + +impl super::UdpSender for UdpSender +where + MakeFut: Fn() -> Fut + Send + Sync + 'static, + Fut: Future> + Send + Sync + 'static, +{ fn poll_send( self: Pin<&mut Self>, transmit: &udp::Transmit, @@ -78,10 +93,7 @@ impl super::UdpSender for UdpSender { let mut this = self.project(); loop { if this.fut.is_none() { - this.fut.set(Some(Box::pin({ - let socket = this.inner.clone(); - async move { socket.io.writable().await } - }))); + this.fut.set(Some((this.make_fut)())); } // We're forced to `unwrap` here because `Fut` may be `!Unpin`, which means we can't safely // obtain an `&mut Fut` after storing it in `self.fut` when `self` is already behind `Pin`, @@ -127,11 +139,11 @@ impl super::UdpSender for UdpSender { impl AsyncUdpSocket for UdpSocket { fn create_sender(self: Arc) -> Pin> { - // TODO(matheus23): There's probably a way to get rid of the double-boxing here (and the box inside UdpSender) - Box::pin(UdpSender { - fut: None, - inner: self, - }) + let socket = self.clone(); + Box::pin(UdpSender::new(self, move || { + let socket = socket.clone(); + async move { socket.io.writable().await } + })) } fn poll_recv(