dope-core 0.15.0

The manifold runtime
Documentation
pub(in crate::backend::uring) mod raw;

use std::mem;

use io_uring::squeue;

use crate::{
    backend::{
        self, bound,
        uring::{engine::lifecycle, ring, submission},
    },
    driver::{self, flight},
    platform::reactor,
};

#[repr(transparent)]
pub(crate) struct Queue<'a> {
    backend: &'a mut backend::Uring,
}

#[repr(transparent)]
pub(in crate::backend::uring) struct Writer<'a>(&'a mut ring::Ready);

const _: () = {
    assert!(mem::size_of::<Queue<'static>>() == mem::size_of::<&'static mut backend::Uring>());
    assert!(mem::size_of::<Writer<'static>>() == mem::size_of::<&'static mut ring::Ready>());
};

impl<'a> Queue<'a> {
    pub(crate) fn new(backend: &'a mut backend::Uring) -> Self {
        Self { backend }
    }
}

impl reactor::Queue for Queue<'_> {
    fn submit<'owner, 'd: 'owner>(
        &mut self,
        submission: bound::Bound<'owner, 'd>,
    ) -> Result<flight::Flight<'d>, driver::SubmitError> {
        let (submission, reservation) = submission.into_parts();
        let entry = submission.bind(reservation.key());
        Writer::new(&mut self.backend.ring).submit_bound(&entry)?;
        Ok(reservation.commit())
    }

    fn cancel(&mut self, flight: &mut flight::Flight<'_>) -> Result<(), driver::SubmitError> {
        Writer::new(&mut self.backend.ring).submit(&submission::Submission::cancel(flight.key()))
    }
}

impl<'a> Writer<'a> {
    pub(in crate::backend::uring) fn new(ring: &'a mut ring::Ready) -> Self {
        Self(ring)
    }

    pub(in crate::backend::uring) fn submit_once(
        &mut self,
        submission: &submission::Submission,
    ) -> Result<(), driver::SubmitError> {
        self.0
            .push_once(submission.entry())
            .map_err(|_| driver::SubmitError)
    }

    pub(in crate::backend::uring) fn submit(
        &mut self,
        submission: &submission::Submission,
    ) -> Result<(), driver::SubmitError> {
        self.submit_entry(submission.entry())
    }

    fn submit_bound(&mut self, submission: &submission::Bound) -> Result<(), driver::SubmitError> {
        self.submit_entry(submission.entry())
    }

    fn submit_entry(&mut self, entry: &squeue::Entry) -> Result<(), driver::SubmitError> {
        self.0.push(entry).map_err(|_| driver::SubmitError)
    }

    pub(in crate::backend::uring) fn try_close(
        &mut self,
        work: lifecycle::CloseWork,
    ) -> Result<(), lifecycle::CloseWork> {
        use libc::SHUT_RDWR;
        let slot = work.slot();
        let shut = submission::Submission::shutdown_linked_at(slot, SHUT_RDWR);
        let close = submission::Submission::close_at(slot);
        let entries = [shut.entry().clone(), close.entry().clone()];
        match self.0.push_multiple_once(&entries) {
            Ok(()) => Ok(()),
            Err(_) => Err(work),
        }
    }
}