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 use manual::Manual;
27pub use scope::Scope;
28
29#[derive(Debug)]
31pub enum Cause<'a> {
32 Drive(&'a drive::Error),
33 Quiesce {
34 drive: &'a drive::Error,
35 disarm: Option<Errno>,
36 },
37 Install {
38 cause: &'a InstallError,
39 disarm: Option<Errno>,
40 },
41}
42
43#[derive(Debug)]
44pub enum Kind<'a, T> {
45 Drive(&'a drive::Error),
46 Quiesce {
47 output: T,
48 drive: &'a drive::Error,
49 disarm: Option<Errno>,
50 },
51 Install {
52 cause: &'a InstallError,
53 disarm: Option<Errno>,
54 },
55}
56
57impl<'a, T> Kind<'a, T> {
58 pub fn map<U>(self, map: impl FnOnce(T) -> U) -> Kind<'a, U> {
59 match self {
60 Self::Drive(error) => Kind::Drive(error),
61 Self::Quiesce {
62 output,
63 drive,
64 disarm,
65 } => Kind::Quiesce {
66 output: map(output),
67 drive,
68 disarm,
69 },
70 Self::Install { cause, disarm } => Kind::Install { cause, disarm },
71 }
72 }
73}
74
75pub(crate) struct Core<'a, 'd, Q> {
76 pub(crate) scope: life::Scope<'a, 'd>,
77 pub(super) pending: Option<Event<'d>>,
78 lifecycle: &'a Q,
79}
80
81impl<'a, 'd, Q> Core<'a, 'd, Q> {
82 pub(super) fn new(scope: life::Scope<'a, 'd>, source: &'a Q) -> Self {
83 Self {
84 scope,
85 pending: None,
86 lifecycle: source,
87 }
88 }
89
90 fn admit(&self, start: Option<clock::Deadline<'d>>) -> StdResult<clock::Sample, drive::Error> {
91 let now = start.map_or_else(time::Instant::now, clock::Deadline::into_raw);
92 self.check_time(now)?;
93 Ok(clock::Sample::new(now))
94 }
95
96 fn check_time(&self, now: time::Instant) -> StdResult<(), drive::Error> {
97 let current = self.scope.driver_ref().clock().now().into_raw();
98 if now < current {
99 return Err(drive::Error::regression(now, current));
100 }
101 Ok(())
102 }
103}
104
105const _: () = {
106 assert!(
107 mem::size_of::<Core<'static, 'static, ()>>()
108 == mem::size_of::<life::Scope<'static, 'static>>()
109 + mem::size_of::<Option<Event<'static>>>()
110 + mem::size_of::<usize>()
111 );
112};
113
114#[derive(Debug, Default)]
116pub struct Completion {
117 quiesce: Option<drive::Error>,
118}
119
120impl Completion {
121 pub const fn new() -> Self {
122 Self { quiesce: None }
123 }
124
125 pub(crate) fn failed<T>(
126 &mut self,
127 output: T,
128 drive: drive::Error,
129 disarm: Option<Errno>,
130 ) -> Error<'_, T> {
131 let drive = self.quiesce.insert(drive);
132 Error::Quiesce {
133 output,
134 drive,
135 disarm,
136 }
137 }
138}