fiona 0.1.0

Concurrent runtime written against liburing
Documentation
use crate as fiona;

#[derive(Clone)]
pub struct FdState {
  p: std::rc::Rc<std::cell::UnsafeCell<FdStateImpl>>,
}

pub struct FdStateImpl {
  pub initiated: bool,
  pub done: bool,
  pub disarmed: bool,
  pub fd: i32,
  pub res: i32,
  pub task: Option<*mut fiona::Task>,
  pub op: Op,
}

pub enum Op {
  Null,
  Timer(TimerState),
  Timeout(TimeoutState),
  Accept(AcceptState),
  Connect(ConnectState),
  Read(ReadState),
  Write(WriteState),
}

pub struct TimerState {
  pub buf: u64,
}

pub struct TimeoutState {
  pub tspec: fiona::libc::kernel_timespec,
}

#[derive(Clone)]
pub struct AcceptState {
  pub addr_in: fiona::ip::tcp::sockaddr_in,
  pub addr_len: u32,
}

pub struct ConnectState {
  pub addr_in: fiona::ip::tcp::sockaddr_in,
}

pub struct ReadState {
  pub buf: Option<Vec<u8>>,
}

pub struct WriteState {
  pub buf: Option<Vec<u8>>,
}

impl FdState {
  #[must_use]
  pub fn new(fd: i32, op: Op) -> Self {
    Self {
      p: std::rc::Rc::new(std::cell::UnsafeCell::new(FdStateImpl {
        initiated: false,
        done: false,
        disarmed: false,
        fd,
        res: -1,
        task: None,
        op,
      })),
    }
  }

  #[must_use]
  pub fn get(&self) -> *mut FdStateImpl {
    self.p.get()
  }

  #[must_use]
  pub fn into_raw(self) -> *mut FdStateImpl {
    std::rc::Rc::into_raw(self.p) as *mut _
  }

  pub unsafe fn from_raw(p: *mut FdStateImpl) -> Self {
    Self {
      p: std::rc::Rc::from_raw(p.cast()),
    }
  }
}

#[derive(Clone)]
pub struct CancelHandle {
  fds: FdState,
  ex: fiona::Executor,
}

impl CancelHandle {
  #[must_use]
  pub fn new(fds: FdState, ex: fiona::Executor) -> Self {
    Self { fds, ex }
  }

  pub fn cancel(self) {
    let p = self.fds.get();
    if unsafe { (*p).disarmed } {
      return;
    }

    let ring = self.ex.get_ring();
    let sqe = unsafe { fiona::liburing::make_sqe(ring) };
    unsafe {
      fiona::liburing::io_uring_prep_cancel(
        sqe,
        p.cast::<fiona::libc::c_void>(),
        0,
      );
    }

    unsafe {
      fiona::liburing::io_uring_submit(ring);
    }
  }

  pub fn disarm(&mut self) {
    let p = self.fds.get();
    unsafe {
      (*p).disarmed = true;
    }
  }
}