dope_runtime/executor/session/
mod.rs1use std::{mem, result::Result as StdResult, time};
2
3use dope_core::{
4 Errno,
5 driver::{life, schedule::clock},
6 io::Event,
7};
8
9use crate::executor::{InstallError, drive};
10
11mod access;
12mod app;
13mod error;
14mod lent;
15mod manual;
16pub(crate) mod run;
17mod scope;
18
19pub use access::Access;
20pub use app::App;
21pub use error::Error;
22pub type Result<'report, T> = std::result::Result<T, Error<'report, T>>;
24
25pub use drive::block::Fixed;
26pub(crate) use lent::Lent;
27pub use manual::Manual;
28pub use scope::Scope;
29
30#[derive(Debug)]
32pub enum Cause<'a> {
33 Drive(&'a drive::Error),
34 Quiesce {
35 drive: &'a drive::Error,
36 disarm: Option<Errno>,
37 },
38 Install {
39 cause: &'a InstallError,
40 disarm: Option<Errno>,
41 },
42}
43
44#[derive(Debug)]
45pub enum Kind<'a, T> {
46 Drive(&'a drive::Error),
47 Quiesce {
48 output: T,
49 drive: &'a drive::Error,
50 disarm: Option<Errno>,
51 },
52 Install {
53 cause: &'a InstallError,
54 disarm: Option<Errno>,
55 },
56}
57
58impl<'a, T> Kind<'a, T> {
59 pub fn map<U>(self, map: impl FnOnce(T) -> U) -> Kind<'a, U> {
60 match self {
61 Self::Drive(error) => Kind::Drive(error),
62 Self::Quiesce {
63 output,
64 drive,
65 disarm,
66 } => Kind::Quiesce {
67 output: map(output),
68 drive,
69 disarm,
70 },
71 Self::Install { cause, disarm } => Kind::Install { cause, disarm },
72 }
73 }
74}
75
76pub(crate) struct Core<'a, 'd, Q> {
77 pub(crate) scope: life::Scope<'a, 'd>,
78 pub(super) pending: Option<Event<'d>>,
79 lifecycle: &'a Q,
80}
81
82impl<'a, 'd, Q> Core<'a, 'd, Q> {
83 pub(super) fn new(scope: life::Scope<'a, 'd>, source: &'a Q) -> Self {
84 Self {
85 scope,
86 pending: None,
87 lifecycle: source,
88 }
89 }
90
91 fn admit(&self, start: Option<clock::Deadline<'d>>) -> StdResult<clock::Sample, drive::Error> {
92 let now = start.map_or_else(time::Instant::now, clock::Deadline::into_raw);
93 self.check_time(now)?;
94 Ok(clock::Sample::new(now))
95 }
96
97 fn check_time(&self, now: time::Instant) -> StdResult<(), drive::Error> {
98 let current = self.scope.driver_ref().clock().now().into_raw();
99 if now < current {
100 return Err(drive::Error::regression(now, current));
101 }
102 Ok(())
103 }
104}
105
106const _: () = {
107 assert!(
108 mem::size_of::<Core<'static, 'static, ()>>()
109 == mem::size_of::<life::Scope<'static, 'static>>()
110 + mem::size_of::<Option<Event<'static>>>()
111 + mem::size_of::<usize>()
112 );
113};
114
115#[derive(Debug, Default)]
117pub struct Completion {
118 quiesce: Option<drive::Error>,
119}
120
121impl Completion {
122 pub const fn new() -> Self {
123 Self { quiesce: None }
124 }
125
126 pub(crate) fn failed<T>(
127 &mut self,
128 output: T,
129 drive: drive::Error,
130 disarm: Option<Errno>,
131 ) -> Error<'_, T> {
132 let drive = self.quiesce.insert(drive);
133 Error::Quiesce {
134 output,
135 drive,
136 disarm,
137 }
138 }
139}