use std::io;
pub use OpCode as IourOpCode;
use compio_buf::BufResult;
use crate::control::Carrier;
pub enum OpEntry {
Submission(io_uring::squeue::Entry),
#[cfg(feature = "io-uring-sqe128")]
Submission128(io_uring::squeue::Entry128),
Blocking,
}
pub unsafe trait OpCode {
type Control: Default;
unsafe fn init(&mut self, _: &mut Self::Control) {}
fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry;
fn create_entry_fallback(&mut self, _: &mut Self::Control) -> OpEntry {
OpEntry::Blocking
}
fn call_blocking(&mut self, _: &mut Self::Control) -> io::Result<usize> {
unreachable!("this operation is asynchronous")
}
unsafe fn set_result(
&mut self,
_: &mut Self::Control,
_: &io::Result<usize>,
_: &crate::Extra,
) {
}
unsafe fn push_multishot(
&mut self,
_: &mut Self::Control,
_: io::Result<usize>,
_: crate::Extra,
) {
unreachable!("this operation is not multishot")
}
fn pop_multishot(
&mut self,
_: &mut Self::Control,
) -> Option<BufResult<usize, crate::sys::Extra>> {
unreachable!("this operation is not multishot")
}
}
impl OpEntry {
pub(crate) fn with_extra(self, extra: &crate::Extra) -> Self {
let Some(extra) = extra.try_as_iour() else {
return self;
};
match self {
Self::Submission(mut entry) => Self::Submission({
if let Some(personality) = extra.get_personality() {
entry = entry.personality(personality);
}
entry.flags(extra.get_sqe_flags())
}),
#[cfg(feature = "io-uring-sqe128")]
Self::Submission128(mut entry) => Self::Submission128({
if let Some(personality) = extra.get_personality() {
entry = entry.personality(personality);
}
entry.flags(extra.get_sqe_flags())
}),
Self::Blocking => Self::Blocking,
}
}
}
pub(crate) trait Carry {
fn create_entry(&mut self) -> OpEntry;
fn create_entry_fallback(&mut self) -> OpEntry;
fn call_blocking(&mut self) -> io::Result<usize>;
unsafe fn set_result(&mut self, _: &io::Result<usize>, _: &crate::Extra);
unsafe fn push_multishot(&mut self, _: io::Result<usize>, _: crate::Extra);
fn pop_multishot(&mut self) -> Option<BufResult<usize, crate::sys::Extra>>;
}
impl<T: crate::OpCode> Carry for Carrier<T> {
fn create_entry(&mut self) -> OpEntry {
let (op, control) = self.as_iour();
op.create_entry(control)
}
fn create_entry_fallback(&mut self) -> OpEntry {
let (op, control) = self.as_iour();
op.create_entry_fallback(control)
}
fn call_blocking(&mut self) -> io::Result<usize> {
let (op, control) = self.as_iour();
op.call_blocking(control)
}
unsafe fn set_result(&mut self, result: &io::Result<usize>, extra: &crate::Extra) {
let (op, control) = self.as_iour();
unsafe { OpCode::set_result(op, control, result, extra) }
}
unsafe fn push_multishot(&mut self, result: io::Result<usize>, extra: crate::Extra) {
let (op, control) = self.as_iour();
unsafe { op.push_multishot(control, result, extra) }
}
fn pop_multishot(&mut self) -> Option<BufResult<usize, crate::sys::Extra>> {
let (op, control) = self.as_iour();
op.pop_multishot(control)
}
}
impl From<io_uring::squeue::Entry> for OpEntry {
fn from(value: io_uring::squeue::Entry) -> Self {
Self::Submission(value)
}
}
#[cfg(feature = "io-uring-sqe128")]
impl From<io_uring::squeue::Entry128> for OpEntry {
fn from(value: io_uring::squeue::Entry128) -> Self {
Self::Submission128(value)
}
}