Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
use std::{io, net};
trait RawSysCallsTraitOrSomething {
fn bind_udp(&self, addr: net::SocketAddr) -> io::Result<UdpSocket> {}
fn set_ttl_udp(&self, socket: usize, ttl: u32) -> io::Result<()> {}
fn read(&self, socket: usize, buf: &mut [u8]) -> io::Result<usize> {}
}
cfg_syscall! {
// When syscall is enabled
type UdpSocket = udp::UdpSocket;
struct SysCalls {
/// This is `DefaultSyscalls` if another `RawSysCallsTraitOrSomething`
/// is not supplied to the runtime.
obj: Arc<dyn RawSysCallsTraitOrSomething>
}
impl SysCalls {
fn bind_udp(&self, addr: net::SocketAddr) -> io::Result<UdpSocket> {
self.obj.bind_udp()
}
}
struct DefaultSyscalls;
// This is where I get a bit confused and it's unclear that this is less complicated.
// In order to have a default implementation of RawSysCallsTraitOrSomething, it seems
// we will need to access real resources like a `UdpSocket` via the `socket: usize`
impl RawSysCallsTraitOrSomething for DefaultSyscalls {
fn bind_udp(&self, addr: net::SocketAddr) -> io::Result<UdpSocket> {}
fn set_ttl_udp(&self, socket: usize, ttl: u32) -> io::Result<()> {}
fn read(&self, socket: usize, buf: &mut [u8]) -> io::Result<usize> {}
}
mod udp {
struct UpdSocket {
id: usize,
obj: Arc<dyn RawSysCallsTraitOrSomething>,
}
impl UdpSocket {
/// These methods on UdpSocket must always match the methods on `mio::net::UdpSocket`.
fn set_ttl(&self, ttl: u32) -> io::Result<()> {
self.obj.set_ttl(self.id, ttl)
}
}
impl Read for UdpSocket {...}
impl Write for UdpSocket {...}
impl Evented for UdpSocket {...}
}
}
cfg_not_syscall! {
type UdpSocket = mio::net::UdpSocket;
struct SysCalls;
impl Syscalls {
fn bind_udp(&self, addr: net::SocketAddr) -> io::Result<UdpSocket> {
mio::net::UdpSocket::bind(addr)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment