dope-kqueue 0.2.1

Thin io_uring adaptor with "Manifolds"
Documentation
use std::cell::RefCell;
use std::rc::Rc;

use dope_core::driver::ProvidedRingOps;

pub struct ProvidedRing {
    inner: Rc<RefCell<Inner>>,
}

struct Inner {
    buf_len: u32,
    bufs: Vec<Box<[u8]>>,
    free: Vec<u16>,
}

impl ProvidedRing {
    pub(crate) fn new(entries: u16, buf_len: u32) -> Self {
        let n = entries as usize;
        let bufs = (0..n)
            .map(|_| vec![0u8; buf_len as usize].into_boxed_slice())
            .collect();
        let free = (0..entries).rev().collect();
        Self {
            inner: Rc::new(RefCell::new(Inner {
                buf_len,
                bufs,
                free,
            })),
        }
    }

    pub(crate) fn group(&self) -> (u16, u32) {
        let inner = self.inner.borrow();
        (Self::BGID, inner.buf_len)
    }

    const BGID: u16 = 0;

    pub(crate) fn make_buf(&self, bid: u16, len: usize) -> ProvidedBuf {
        let (ptr, _cap) = self.ptr_len(bid);
        ProvidedBuf {
            bid,
            ptr,
            len,
            ring: self.inner.clone(),
            released: false,
        }
    }

    pub(crate) fn pop_free(&self) -> Option<u16> {
        self.inner.borrow_mut().free.pop()
    }
}

impl ProvidedRingOps for ProvidedRing {
    fn ptr_len(&self, bid: u16) -> (*mut u8, usize) {
        let inner = self.inner.borrow();
        let buf = &inner.bufs[bid as usize];
        (buf.as_ptr() as *mut u8, buf.len())
    }

    fn defer(&mut self, bid: u16) {
        self.inner.borrow_mut().free.push(bid);
    }
}

pub struct ProvidedBuf {
    bid: u16,
    ptr: *mut u8,
    len: usize,
    ring: Rc<RefCell<Inner>>,
    released: bool,
}

impl ProvidedBuf {
    pub fn len(&self) -> usize {
        self.len
    }

    pub fn is_empty(&self) -> bool {
        self.len == 0
    }

    pub fn as_slice(&self) -> &[u8] {
        unsafe { std::slice::from_raw_parts(self.ptr, self.len) }
    }

    #[allow(clippy::should_implement_trait)]
    pub fn as_mut(&mut self) -> &mut [u8] {
        unsafe { std::slice::from_raw_parts_mut(self.ptr, self.len) }
    }
}

impl AsRef<[u8]> for ProvidedBuf {
    fn as_ref(&self) -> &[u8] {
        self.as_slice()
    }
}

impl Drop for ProvidedBuf {
    fn drop(&mut self) {
        if self.released {
            return;
        }
        self.ring.borrow_mut().free.push(self.bid);
    }
}