103 lines
2.5 KiB
Rust
103 lines
2.5 KiB
Rust
use std::{
|
|
future::Future,
|
|
io,
|
|
pin::Pin,
|
|
sync::Arc,
|
|
task::{Context, Poll, ready},
|
|
time::Instant,
|
|
};
|
|
|
|
use tokio::{
|
|
io::Interest,
|
|
time::{Sleep, sleep_until},
|
|
};
|
|
|
|
use super::{AsyncTimer, AsyncUdpSocket, Runtime, UdpPollHelper};
|
|
|
|
/// A Quinn runtime for Tokio
|
|
#[derive(Debug)]
|
|
pub struct TokioRuntime;
|
|
|
|
impl Runtime for TokioRuntime {
|
|
fn new_timer(&self, t: Instant) -> Pin<Box<dyn AsyncTimer>> {
|
|
Box::pin(sleep_until(t.into()))
|
|
}
|
|
|
|
fn spawn(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
|
|
tokio::spawn(future);
|
|
}
|
|
|
|
fn wrap_udp_socket(&self, sock: std::net::UdpSocket) -> io::Result<Arc<dyn AsyncUdpSocket>> {
|
|
Ok(Arc::new(UdpSocket {
|
|
inner: udp::UdpSocketState::new((&sock).into())?,
|
|
io: tokio::net::UdpSocket::from_std(sock)?,
|
|
}))
|
|
}
|
|
|
|
fn now(&self) -> Instant {
|
|
tokio::time::Instant::now().into_std()
|
|
}
|
|
}
|
|
|
|
impl AsyncTimer for Sleep {
|
|
fn reset(self: Pin<&mut Self>, t: Instant) {
|
|
Self::reset(self, t.into())
|
|
}
|
|
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<()> {
|
|
Future::poll(self, cx)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct UdpSocket {
|
|
io: tokio::net::UdpSocket,
|
|
inner: udp::UdpSocketState,
|
|
}
|
|
|
|
impl AsyncUdpSocket for UdpSocket {
|
|
fn create_io_poller(self: Arc<Self>) -> Pin<Box<dyn super::UdpPoller>> {
|
|
Box::pin(UdpPollHelper::new(move || {
|
|
let socket = self.clone();
|
|
async move { socket.io.writable().await }
|
|
}))
|
|
}
|
|
|
|
fn try_send(&self, transmit: &udp::Transmit) -> io::Result<()> {
|
|
self.io.try_io(Interest::WRITABLE, || {
|
|
self.inner.send((&self.io).into(), transmit)
|
|
})
|
|
}
|
|
|
|
fn poll_recv(
|
|
&self,
|
|
cx: &mut Context,
|
|
bufs: &mut [std::io::IoSliceMut<'_>],
|
|
meta: &mut [udp::RecvMeta],
|
|
) -> Poll<io::Result<usize>> {
|
|
loop {
|
|
ready!(self.io.poll_recv_ready(cx))?;
|
|
if let Ok(res) = self.io.try_io(Interest::READABLE, || {
|
|
self.inner.recv((&self.io).into(), bufs, meta)
|
|
}) {
|
|
return Poll::Ready(Ok(res));
|
|
}
|
|
}
|
|
}
|
|
|
|
fn local_addr(&self) -> io::Result<std::net::SocketAddr> {
|
|
self.io.local_addr()
|
|
}
|
|
|
|
fn may_fragment(&self) -> bool {
|
|
self.inner.may_fragment()
|
|
}
|
|
|
|
fn max_transmit_segments(&self) -> usize {
|
|
self.inner.max_gso_segments()
|
|
}
|
|
|
|
fn max_receive_segments(&self) -> usize {
|
|
self.inner.gro_segments()
|
|
}
|
|
}
|