iroh_quinn/runtime/
smol.rs1use 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#[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}