#![cfg_attr(windows, allow(unsafe_code))]
#[cfg(unix)]
use crate::fd::FdReadyDriver;
#[cfg(unix)]
use crate::fd::PollFdReady;
use crate::socket::PollSocketReady;
use crate::socket::SocketReadyDriver;
#[cfg(windows)]
use crate::sys::overlapped::IoOverlapped;
#[cfg(windows)]
use crate::sys::overlapped::OverlappedIoDriver;
use crate::task::Spawn;
use crate::timer::PollTimer;
use crate::timer::TimerDriver;
use crate::wait::PollWait;
use crate::wait::WaitDriver;
use smallbox::space::S4;
use smallbox::SmallBox;
use std::io;
#[cfg(unix)]
use std::os::unix::prelude::*;
#[cfg(windows)]
use std::os::windows::prelude::*;
use std::sync::Arc;
pub type PollImpl<T> = SmallBox<T, S4>;
pub trait Driver: 'static + Send + Sync {
fn new_dyn_timer(&self) -> PollImpl<dyn PollTimer>;
#[cfg(unix)]
fn new_dyn_fd_ready(&self, fd: RawFd) -> io::Result<PollImpl<dyn PollFdReady>>;
#[cfg(windows)]
fn new_dyn_socket_ready(&self, socket: RawSocket) -> io::Result<PollImpl<dyn PollSocketReady>>;
#[cfg(unix)]
fn new_dyn_socket_ready(&self, socket: RawFd) -> io::Result<PollImpl<dyn PollSocketReady>>;
#[cfg(windows)]
fn new_dyn_wait(&self, handle: RawHandle) -> io::Result<PollImpl<dyn PollWait>>;
#[cfg(unix)]
fn new_dyn_wait(&self, fd: RawFd, read_size: usize) -> io::Result<PollImpl<dyn PollWait>>;
#[cfg(windows)]
unsafe fn new_dyn_overlapped_file(
&self,
handle: RawHandle,
) -> io::Result<PollImpl<dyn IoOverlapped>>;
}
#[cfg(unix)]
impl<T> Driver for T
where
T: 'static + Send + Sync + FdReadyDriver + TimerDriver + SocketReadyDriver + WaitDriver,
{
fn new_dyn_timer(&self) -> PollImpl<dyn PollTimer> {
smallbox::smallbox!(self.new_timer())
}
fn new_dyn_fd_ready(&self, fd: RawFd) -> io::Result<PollImpl<dyn PollFdReady>> {
Ok(smallbox::smallbox!(self.new_fd_ready(fd)?))
}
fn new_dyn_socket_ready(&self, socket: RawFd) -> io::Result<PollImpl<dyn PollSocketReady>> {
Ok(smallbox::smallbox!(self.new_socket_ready(socket)?))
}
fn new_dyn_wait(&self, fd: RawFd, read_size: usize) -> io::Result<PollImpl<dyn PollWait>> {
Ok(smallbox::smallbox!(self.new_wait(fd, read_size)?))
}
}
#[cfg(windows)]
impl<T> Driver for T
where
T: 'static + Send + Sync + TimerDriver + SocketReadyDriver + WaitDriver + OverlappedIoDriver,
{
fn new_dyn_timer(&self) -> PollImpl<dyn PollTimer> {
smallbox::smallbox!(self.new_timer())
}
fn new_dyn_socket_ready(&self, socket: RawSocket) -> io::Result<PollImpl<dyn PollSocketReady>> {
Ok(smallbox::smallbox!(self.new_socket_ready(socket)?))
}
fn new_dyn_wait(&self, handle: RawHandle) -> io::Result<PollImpl<dyn PollWait>> {
Ok(smallbox::smallbox!(self.new_wait(handle)?))
}
unsafe fn new_dyn_overlapped_file(
&self,
handle: RawHandle,
) -> io::Result<PollImpl<dyn IoOverlapped>> {
Ok(smallbox::smallbox!(unsafe {
self.new_overlapped_file(handle)
}?))
}
}
#[cfg(unix)]
impl Driver for Box<dyn Driver> {
fn new_dyn_timer(&self) -> PollImpl<dyn PollTimer> {
self.as_ref().new_dyn_timer()
}
fn new_dyn_fd_ready(&self, fd: RawFd) -> io::Result<PollImpl<dyn PollFdReady>> {
self.as_ref().new_dyn_fd_ready(fd)
}
fn new_dyn_socket_ready(&self, socket: RawFd) -> io::Result<PollImpl<dyn PollSocketReady>> {
self.as_ref().new_dyn_socket_ready(socket)
}
fn new_dyn_wait(&self, fd: RawFd, read_size: usize) -> io::Result<PollImpl<dyn PollWait>> {
self.as_ref().new_dyn_wait(fd, read_size)
}
}
#[cfg(windows)]
impl Driver for Box<dyn Driver> {
fn new_dyn_timer(&self) -> PollImpl<dyn PollTimer> {
self.as_ref().new_dyn_timer()
}
fn new_dyn_socket_ready(&self, socket: RawSocket) -> io::Result<PollImpl<dyn PollSocketReady>> {
self.as_ref().new_dyn_socket_ready(socket)
}
fn new_dyn_wait(&self, handle: RawHandle) -> io::Result<PollImpl<dyn PollWait>> {
self.as_ref().new_dyn_wait(handle)
}
unsafe fn new_dyn_overlapped_file(
&self,
handle: RawHandle,
) -> io::Result<PollImpl<dyn IoOverlapped>> {
unsafe { self.as_ref().new_dyn_overlapped_file(handle) }
}
}
#[cfg(unix)]
impl Driver for Arc<dyn Driver> {
fn new_dyn_timer(&self) -> PollImpl<dyn PollTimer> {
self.as_ref().new_dyn_timer()
}
fn new_dyn_fd_ready(&self, fd: RawFd) -> io::Result<PollImpl<dyn PollFdReady>> {
self.as_ref().new_dyn_fd_ready(fd)
}
fn new_dyn_socket_ready(&self, socket: RawFd) -> io::Result<PollImpl<dyn PollSocketReady>> {
self.as_ref().new_dyn_socket_ready(socket)
}
fn new_dyn_wait(&self, fd: RawFd, read_size: usize) -> io::Result<PollImpl<dyn PollWait>> {
self.as_ref().new_dyn_wait(fd, read_size)
}
}
#[cfg(windows)]
impl Driver for Arc<dyn Driver> {
fn new_dyn_timer(&self) -> PollImpl<dyn PollTimer> {
self.as_ref().new_dyn_timer()
}
fn new_dyn_socket_ready(&self, socket: RawSocket) -> io::Result<PollImpl<dyn PollSocketReady>> {
self.as_ref().new_dyn_socket_ready(socket)
}
fn new_dyn_wait(&self, handle: RawHandle) -> io::Result<PollImpl<dyn PollWait>> {
self.as_ref().new_dyn_wait(handle)
}
unsafe fn new_dyn_overlapped_file(
&self,
handle: RawHandle,
) -> io::Result<PollImpl<dyn IoOverlapped>> {
unsafe { self.as_ref().new_dyn_overlapped_file(handle) }
}
}
pub trait SpawnDriver: Spawn + Driver {}
impl<T: Spawn + Driver> SpawnDriver for T {}