#[cfg(feature = "allocator_api")]
use std::alloc::Allocator;
use std::{io, time::Duration};
use crate::vec_deque_alloc;
#[cfg(unix)]
mod unix;
cfg_if::cfg_if! {
if #[cfg(target_os = "windows")] {
mod iocp;
#[cfg(feature="time")]
mod time;
pub use iocp::*;
} else if #[cfg(target_os = "linux")] {
mod iour;
pub use iour::*;
} else if #[cfg(unix)]{
mod mio;
#[cfg(feature="time")]
mod time;
pub use self::mio::*;
}
}
pub trait CompleteIo<'arena> {
fn attach(&mut self, fd: RawFd) -> io::Result<()>;
fn try_cancel(&mut self, user_data: usize) -> Result<(), ()>;
fn try_push<O: OpCode>(&mut self, op: Operation<'arena, O>)
-> Result<(), Operation<'arena, O>>;
fn try_push_dyn(&mut self, op: OpObject<'arena>) -> Result<(), OpObject<'arena>>;
fn push_queue<#[cfg(feature = "allocator_api")] A: Allocator + Unpin + 'arena>(
&mut self,
ops_queue: &mut vec_deque_alloc!(OpObject<'arena>, A),
);
fn capacity_left(&self) -> usize;
unsafe fn submit_and_wait_completed(
&mut self,
timeout: Option<Duration>,
completed: &mut impl Extend<Entry>,
) -> io::Result<()>;
}
pub struct Operation<'a, O: OpCode> {
op: &'a mut O,
user_data: usize,
}
impl<'a, O: OpCode> Operation<'a, O> {
pub fn new(op: &'a mut O, user_data: usize) -> Self {
Self { op, user_data }
}
pub fn opcode(&mut self) -> &mut O {
self.op
}
pub fn user_data(&self) -> usize {
self.user_data
}
}
impl<'a, O: OpCode> From<(&'a mut O, usize)> for Operation<'a, O> {
fn from((op, user_data): (&'a mut O, usize)) -> Self {
Self::new(op, user_data)
}
}
impl<'a, O: OpCode> From<Operation<'a, O>> for (&'a mut O, usize) {
fn from(other: Operation<'a, O>) -> Self {
(other.op, other.user_data)
}
}
pub struct OpObject<'a> {
op: &'a mut dyn OpCode,
user_data: usize,
}
impl<'a> OpObject<'a> {
pub fn new(op: &'a mut dyn OpCode, user_data: usize) -> Self {
Self { op, user_data }
}
pub fn opcode(&mut self) -> &mut dyn OpCode {
self.op
}
pub fn user_data(&self) -> usize {
self.user_data
}
}
impl<'a, O: OpCode> From<(&'a mut O, usize)> for OpObject<'a> {
fn from((op, user_data): (&'a mut O, usize)) -> Self {
Self::new(op, user_data)
}
}
impl<'a> From<(&'a mut dyn OpCode, usize)> for OpObject<'a> {
fn from((op, user_data): (&'a mut dyn OpCode, usize)) -> Self {
Self::new(op, user_data)
}
}
impl<'a, O: OpCode> From<Operation<'a, O>> for OpObject<'a> {
fn from(other: Operation<'a, O>) -> Self {
Self::new(other.op, other.user_data)
}
}
impl<'a> From<OpObject<'a>> for (&'a mut dyn OpCode, usize) {
fn from(other: OpObject<'a>) -> Self {
(other.op, other.user_data)
}
}
#[derive(Debug)]
pub struct Entry {
user_data: usize,
result: io::Result<usize>,
}
impl Entry {
pub(crate) fn new(user_data: usize, result: io::Result<usize>) -> Self {
Self { user_data, result }
}
pub fn user_data(&self) -> usize {
self.user_data
}
pub fn into_result(self) -> io::Result<usize> {
self.result
}
}