Skip to main content

dope_core/driver/lifecycle/
mod.rs

1use std::io;
2
3use o3::cell::{brand, region};
4
5use crate::{
6    backend::{self, fixed},
7    driver::{
8        self, flight,
9        ops::{reactors, retirements},
10        schedule,
11        schedule::timer,
12    },
13};
14
15mod domain;
16mod finalize;
17mod install;
18mod sealed;
19
20pub use domain::Domain;
21pub(crate) use domain::Source;
22pub use finalize::Finalize;
23pub use install::Install;
24pub(in crate::driver) use sealed::Lease;
25pub mod quiesce;
26#[doc(hidden)]
27pub mod raw;
28pub mod routing;
29
30pub struct Scope<'d> {
31    driver: driver::Reference<'d>,
32    backend: &'d mut backend::Backend,
33    flights: &'d mut flight::Arena,
34    work: schedule::Work,
35    region: region::Token<'d>,
36    token: brand::Token<'d>,
37    timer: &'d timer::Timer<'d>,
38    _owner: quiesce::Lease,
39}
40
41impl<'d> Scope<'d> {
42    pub(in crate::driver) fn new(
43        driver: driver::Reference<'d>,
44        backend: &'d mut backend::Backend,
45        flights: &'d mut flight::Arena,
46        region: region::Token<'d>,
47        token: brand::Token<'d>,
48        timer: &'d timer::Timer<'d>,
49        owner: quiesce::Lease,
50    ) -> Self {
51        Self {
52            driver,
53            backend,
54            flights,
55            work: schedule::Work::new(),
56            region,
57            token,
58            timer,
59            _owner: owner,
60        }
61    }
62
63    pub fn context(&mut self) -> driver::Context<'_, 'd> {
64        driver::Context::new(
65            self.driver,
66            &mut *self.backend,
67            &mut *self.flights,
68            &mut self.region,
69            self.timer,
70        )
71    }
72
73    pub fn token(&mut self) -> &mut brand::Token<'d> {
74        &mut self.token
75    }
76
77    /// Runs with the sole scheduler coordinator for this driver scope.
78    ///
79    /// ```compile_fail
80    /// use dope_core::driver::{lifecycle::Scope, schedule::Controller};
81    ///
82    /// fn escape<'d>(scope: &mut Scope<'d>) -> Controller<'static, 'd> {
83    ///     scope.with_turn(|_, _, turn| turn)
84    /// }
85    /// ```
86    pub fn with_turn<R>(
87        &mut self,
88        run: impl for<'scope> FnOnce(
89            &'scope mut brand::Token<'d>,
90            driver::Context<'scope, 'd>,
91            schedule::Controller<'scope, 'd>,
92        ) -> R,
93    ) -> R {
94        let context = driver::Context::new(
95            self.driver,
96            &mut *self.backend,
97            &mut *self.flights,
98            &mut self.region,
99            self.timer,
100        );
101        run(
102            &mut self.token,
103            context,
104            schedule::Controller::new(self.driver, &mut self.work),
105        )
106    }
107
108    pub fn driver_ref(&self) -> driver::Reference<'d> {
109        self.driver
110    }
111
112    #[doc(hidden)]
113    pub fn final_quiescence(
114        &mut self,
115    ) -> io::Result<(&mut brand::Token<'d>, quiesce::Final<'_, 'd>)> {
116        let context = driver::Context::new(
117            self.driver,
118            &mut *self.backend,
119            &mut *self.flights,
120            &mut self.region,
121            self.timer,
122        );
123        let finalization = quiesce::Final::new(context)?;
124        Ok((&mut self.token, finalization))
125    }
126
127    #[doc(hidden)]
128    pub fn reap_finalized(&mut self) -> io::Result<()> {
129        let mut context = driver::Context::new(
130            self.driver,
131            &mut *self.backend,
132            &mut *self.flights,
133            &mut self.region,
134            self.timer,
135        );
136        reactors::Returned::reclaim_all(&mut context);
137        retirements::Reclaimer::<true>::new(&mut context).all();
138        let (backend, drain) = context.backend_drain();
139        fixed::Finalize::settle(backend, drain)
140    }
141}