dope-core 0.15.1

The manifold runtime
Documentation
use crate::{
    backend::fixed,
    driver::{self, ops, schedule, storage::retirements},
};

pub(crate) enum Retirement {}

pub(in crate::driver) struct Reclaimer<'a, 'scope, 'd, const TERMINAL: bool> {
    context: &'a mut driver::Context<'scope, 'd>,
}

impl<'turn, 'd> schedule::Budget<'turn, 'd, Retirement> {
    pub(crate) fn reclaim(&mut self, context: &mut driver::Context<'_, 'd>) {
        let mut reclaimer = Reclaimer::<false>::new(context);
        while let schedule::Admission::Item(record) = self.admit_with(|| reclaimer.pop()) {
            reclaimer.record(record);
        }
    }
}

impl<'a, 'scope, 'd, const TERMINAL: bool> Reclaimer<'a, 'scope, 'd, TERMINAL> {
    const PHASE: fixed::Phase = if TERMINAL {
        fixed::Phase::Final
    } else {
        fixed::Phase::Active
    };

    pub(in crate::driver) fn new(context: &'a mut driver::Context<'scope, 'd>) -> Self {
        Self { context }
    }

    pub(in crate::driver) fn all(&mut self) {
        while let Some(record) = self.pop() {
            self.record(record);
        }
    }

    fn pop(&self) -> Option<retirements::Record<'d>> {
        let driver = self.context.driver_ref();
        driver.maintenance().pop_deferred_retirement()
    }

    fn record(&mut self, record: retirements::Record<'d>) {
        let context = &mut *self.context;
        match record {
            retirements::Record::Route(id) => {
                ops::Control::release_route(context, id);
            }
            retirements::Record::Retire(retired) => {
                fixed::Lifecycle::retire(context.backend(), retired.into_slot(), Self::PHASE);
            }
            retirements::Record::Descriptor { slot, outbound } => {
                let driver = context.driver_ref();
                match driver.outbound().close_disposition(slot, outbound) {
                    driver::CloseDisposition::Submit(close) => {
                        fixed::Lifecycle::close(context.backend(), close, driver, Self::PHASE);
                    }
                    driver::CloseDisposition::NoSubmit(Some(retired)) => {
                        let slots = driver.outbound().take_retired_slots(retired);
                        fixed::Lifecycle::release_slots(context.backend(), slots);
                    }
                    driver::CloseDisposition::NoSubmit(None) => {}
                }
            }
            retirements::Record::Close { slot } => {
                let driver = context.driver_ref();
                let close = driver::Close::untracked(slot);
                fixed::Lifecycle::close(context.backend(), close, driver, Self::PHASE);
            }
            retirements::Record::OutboundSlots { slots: retired } => {
                let driver = context.driver_ref();
                let slots = driver.outbound().take_retired_slots(retired);
                fixed::Lifecycle::release_slots(context.backend(), slots);
            }
        }
    }
}