iroh_quinn/runtime/
smol.rs

1use std::{
2    future::Future,
3    pin::Pin,
4    task::{Context, Poll},
5    time::Instant,
6};
7use std::{io, sync::Arc, task::ready};
8
9use async_io::Async;
10use async_io::Timer;
11
12use super::AsyncTimer;
13use super::{AsyncUdpSocket, Runtime, UdpSender, UdpSenderHelper, UdpSenderHelperSocket};
14
15/// A Quinn runtime for smol
16#[derive(Debug)]
17pub struct SmolRuntime;
18
19impl Runtime for SmolRuntime {
20    fn new_timer(&self, t: Instant) -> Pin<Box<dyn AsyncTimer>> {
21        Box::pin(Timer::at(t))
22    }
23
24    fn spawn(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
25        ::smol::spawn(future).detach();
26    }
27
28    fn wrap_udp_socket(&self, sock: std::net::UdpSocket) -> io::Result<Box<dyn AsyncUdpSocket>> {
29        Ok(Box::new(UdpSocket::new(sock)?))
30    }
31}
32
33impl AsyncTimer for Timer {
34    fn reset(mut self: Pin<&mut Self>, t: Instant) {
35        self.set_at(t)
36    }
37
38    fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<()> {
39        Future::poll(self, cx).map(|_| ())
40    }
41}
42
43#[derive(Debug, Clone)]
44struct UdpSocket {
45    io: Arc<Async<std::net::UdpSocket>>,
46    inner: Arc<udp::UdpSocketState>,
47}
48
49impl UdpSocket {
50    fn new(sock: std::net::UdpSocket) -> io::Result<Self> {
51        Ok(Self {
52            inner: Arc::new(udp::UdpSocketState::new((&sock).into())?),
53            io: Arc::new(Async::new_nonblocking(sock)?),
54        })
55    }
56}
57
58impl UdpSenderHelperSocket for UdpSocket {
59    fn max_transmit_segments(&self) -> usize {
60        self.inner.max_gso_segments()
61    }
62
63    fn try_send(&self, transmit: &udp::Transmit) -> io::Result<()> {
64        self.inner.send((&self.io).into(), transmit)
65    }
66}
67
68impl AsyncUdpSocket for UdpSocket {
69    fn create_sender(&self) -> Pin<Box<dyn UdpSender>> {
70        Box::pin(UdpSenderHelper::new(self.clone(), |socket: &Self| {
71            let socket = socket.clone();
72            async move { socket.io.writable().await }
73        }))
74    }
75
76    fn poll_recv(
77        &mut self,
78        cx: &mut Context,
79        bufs: &mut [io::IoSliceMut<'_>],
80        meta: &mut [udp::RecvMeta],
81    ) -> Poll<io::Result<usize>> {
82        loop {
83            ready!(self.io.poll_readable(cx))?;
84            if let Ok(res) = self.inner.recv((&self.io).into(), bufs, meta) {
85                return Poll::Ready(Ok(res));
86            }
87        }
88    }
89
90    fn local_addr(&self) -> io::Result<std::net::SocketAddr> {
91        self.io.as_ref().as_ref().local_addr()
92    }
93
94    fn may_fragment(&self) -> bool {
95        self.inner.may_fragment()
96    }
97
98    fn max_receive_segments(&self) -> usize {
99        self.inner.gro_segments()
100    }
101}