cartel-sqlite 0.30.0

SQLite driver for the dope runtime
use crate::{config, engine::retry, sys};
use dope_core::driver::schedule::{clock, ready::wake};
use o3::mem::{self, lease};
use std::{marker, task};

pub(crate) trait Role {
    const FINISH: bool;

    fn limits(config: &config::Config) -> &config::Contention;
}

pub(crate) enum Open {}

pub(crate) enum Call {}

pub(crate) struct Lease<'slot, 'd, R: Role> {
    slot: mem::Lease<Return<'slot, 'd, R>, lease::Open>,
}

struct Return<'slot, 'd, R>(marker::PhantomData<(retry::raw::Loan<'slot, 'd>, R)>);

impl<'slot, 'd, R: Role> Lease<'slot, 'd, R> {
    pub(super) const fn new(slot: retry::raw::Loan<'slot, 'd>) -> Self {
        Self {
            slot: mem::Lease::open(Return(marker::PhantomData), slot),
        }
    }

    pub(crate) fn config(&self) -> &'slot config::Config {
        self.slot.item().config()
    }

    pub(crate) fn defer(
        &mut self,
        now: clock::Moment<'d>,
        fault: sys::Fault,
        wake: wake::Waker<'d>,
    ) -> task::Poll<Result<(), crate::Error>> {
        let limits = R::limits(self.config());
        self.slot
            .item_mut()
            .slot_mut()
            .defer(limits, now, fault, wake)
    }

    pub(crate) fn wait(&self) -> retry::Wait {
        self.slot.item().slot().wait()
    }

    pub(crate) fn poll(
        &mut self,
        now: clock::Moment<'d>,
        wake: wake::Waker<'d>,
    ) -> task::Poll<Result<(), crate::Error>> {
        self.slot.item_mut().slot_mut().poll(now, wake)
    }
}

impl<'slot, 'd, R: Role> mem::Return for Return<'slot, 'd, R> {
    type Item = retry::raw::Loan<'slot, 'd>;

    fn return_item(self, mut slot: Self::Item) {
        if R::FINISH {
            slot.finish();
        }
    }
}

impl Role for Open {
    const FINISH: bool = false;

    fn limits(config: &config::Config) -> &config::Contention {
        &config.work.open.contention
    }
}

impl Role for Call {
    const FINISH: bool = true;

    fn limits(config: &config::Config) -> &config::Contention {
        &config.work.call.contention
    }
}

const _: () = {
    let word = size_of::<usize>();
    assert!(size_of::<Lease<'static, 'static, Open>>() == word);
    assert!(size_of::<Lease<'static, 'static, Call>>() == word);
};