pub use self::OpCode as PollOpCode;
use crate::sys::prelude::*;
#[non_exhaustive]
pub enum OpType {
Fd(Multi<RawFd>),
#[cfg(aio)]
Aio(NonNull<libc::aiocb>),
}
#[derive(Debug)]
#[non_exhaustive]
pub enum Decision {
Completed(usize),
Wait(Multi<WaitArg>),
Blocking,
#[cfg(aio)]
Aio(AioArg),
}
#[derive(Debug, Clone, Copy)]
pub struct WaitArg {
pub fd: RawFd,
pub interest: Interest,
}
pub unsafe trait OpCode {
type Control: Default;
unsafe fn init(&mut self, _: &mut Self::Control) {}
fn pre_submit(&mut self, _: &mut Self::Control) -> io::Result<Decision>;
fn op_type(&mut self, _: &mut Self::Control) -> Option<OpType> {
None
}
fn operate(&mut self, _: &mut Self::Control) -> Poll<io::Result<usize>>;
unsafe fn set_result(
&mut self,
_: &mut Self::Control,
_: &io::Result<usize>,
_: &crate::Extra,
) {
}
}
pub(crate) trait Carry {
fn pre_submit(&mut self) -> io::Result<Decision>;
fn op_type(&mut self) -> Option<OpType>;
fn operate(&mut self) -> Poll<io::Result<usize>>;
unsafe fn set_result(&mut self, _: &io::Result<usize>, _: &crate::Extra);
}
impl OpType {
pub fn fd(fd: RawFd) -> Self {
Self::Fd(Multi::from_buf([fd]))
}
pub fn multi_fd<I: IntoIterator<Item = RawFd>>(fds: I) -> Self {
Self::Fd(Multi::from_iter(fds))
}
}
impl<T: crate::OpCode> Carry for Carrier<T> {
fn pre_submit(&mut self) -> io::Result<Decision> {
let (op, control) = self.as_poll();
op.pre_submit(control)
}
fn op_type(&mut self) -> Option<OpType> {
let (op, control) = self.as_poll();
op.op_type(control)
}
fn operate(&mut self) -> Poll<io::Result<usize>> {
let (op, control) = self.as_poll();
op.operate(control)
}
unsafe fn set_result(&mut self, res: &io::Result<usize>, extra: &crate::Extra) {
let (op, control) = self.as_poll();
unsafe { OpCode::set_result(op, control, res, extra) }
}
}
impl Decision {
pub fn wait_for(fd: RawFd, interest: Interest) -> Self {
Self::Wait(Multi::from_buf([WaitArg { fd, interest }]))
}
pub fn wait_for_many<I: IntoIterator<Item = WaitArg>>(args: I) -> Self {
Self::Wait(Multi::from_iter(args))
}
pub fn wait_readable(fd: RawFd) -> Self {
Self::wait_for(fd, Interest::Readable)
}
pub fn wait_writable(fd: RawFd) -> Self {
Self::wait_for(fd, Interest::Writable)
}
#[cfg(aio)]
pub fn aio(
cb: &mut libc::aiocb,
submit: unsafe extern "C" fn(*mut libc::aiocb) -> i32,
) -> Self {
Self::Aio(AioArg {
aiocbp: NonNull::from(cb),
submit,
})
}
}
impl WaitArg {
pub fn readable(fd: RawFd) -> Self {
Self {
fd,
interest: Interest::Readable,
}
}
pub fn writable(fd: RawFd) -> Self {
Self {
fd,
interest: Interest::Writable,
}
}
}