1use std::{marker, mem, os::fd, pin};
2
3use dope_sys::memory::Context as _;
4pub(in crate::driver) use epochs::Final;
5use finish::Finish;
6use o3::{
7 base::{
8 cell::{brand, region},
9 marker::ThreadBound,
10 },
11 buffer,
12 buffer::storage::{provided, provided::fixed},
13};
14use plans::{Build, Create, Direct, Provided};
15use schedule::state::Core;
16use state::scope;
17
18use crate::{
19 Engine, driver,
20 driver::{
21 life::recovery::{Observe, Recover},
22 retained::flight,
23 route::lease::Registry,
24 schedule,
25 schedule::state,
26 storage,
27 storage::{resident, resident::Alloc},
28 },
29 io,
30};
31
32pub mod creation;
33pub mod domain;
34pub mod finish;
35pub(crate) mod native;
36mod plans;
37pub mod recovery;
38
39#[derive(Clone, Copy, Debug, Eq, PartialEq)]
41pub struct Busy;
42
43pub mod raw;
45
46pub trait Operation<S: storage::Plan, Q: ?Sized>: Sized {
48 type Output;
49
50 fn run<'a, 'p, 'd>(
51 self,
52 scope: Scope<'a, 'd>,
53 storage: storage::Loan<'a, 'p, 'd, S>,
54 source: &'a Q,
55 ) -> Self::Output
56 where
57 'd: 'p,
58 'p: 'a,
59 'd: 'a,
60 Self: 'd,
61 S: 'd,
62 Q: 'd;
63}
64
65pub(crate) struct Local<'d> {
68 pub(crate) driver: driver::Reference<'d>,
69 pub(crate) backend: fixed::Loan<'d, Engine>,
70 pub(in crate::driver) retry: bool,
71 pub(crate) flights: &'d mut flight::Arena,
72 pub(in crate::driver) resident: Alloc<'d>,
73 pub(in crate::driver) routes: Registry,
74 pub(in crate::driver) region: (
75 region::Token<region::Identity<'d>>,
76 region::Token<region::Identity<'d, 1>>,
77 ),
78 pub(crate) lifecycle: Lifecycle<'d>,
79}
80
81pub(crate) struct Lifecycle<'d> {
83 pub(crate) source: Option<fd::BorrowedFd<'d>>,
84 pub(crate) resuming: bool,
85 pub(crate) pending: bool,
86 pub(crate) report: &'d mut dyn FnMut(io::Reclaimed),
87 pub(in crate::driver) recover: &'d dyn recovery::Recover,
88}
89
90impl Lifecycle<'_> {
91 pub(crate) fn report(&mut self, event: io::Reclaimed) {
92 if matches!(event, io::Reclaimed::Shutdown) {
93 let owned = self.source.take().is_some();
94 if self.resuming && owned {
95 self.pending = true;
96 return;
97 }
98 }
99 (self.report)(event);
100 }
101}
102
103pub(in crate::driver) struct State<'d> {
104 local: Local<'d>,
105 work: Core<'d>,
106 token: brand::Token<brand::Identity<'d>>,
107}
108
109impl<'d> State<'d> {
110 fn new(local: Local<'d>, token: brand::Token<brand::Identity<'d>>) -> Self {
111 Self {
112 work: Core::new(local.driver),
113 local,
114 token,
115 }
116 }
117}
118
119mod epochs;
120
121pub(in crate::driver) struct Lease<'a> {
122 driver: pin::Pin<&'a mut driver::Driver>,
123}
124
125#[repr(transparent)]
128pub struct Scope<'a, 'd> {
129 state: &'a mut State<'d>,
130}
131
132impl<'a, 'd> Scope<'a, 'd> {
133 fn new(state: &'a mut State<'d>) -> Self {
134 Self { state }
135 }
136
137 pub fn context(&mut self) -> driver::Context<'_, 'd> {
138 let state = &mut *self.state;
139 driver::Context::new(&mut state.local)
140 }
141
142 pub fn token(&mut self) -> &mut brand::Token<brand::Identity<'d>> {
143 &mut self.state.token
144 }
145
146 pub fn with_turn<R>(
148 &mut self,
149 run: impl for<'scope> FnOnce(
150 &'scope mut brand::Token<brand::Identity<'d>>,
151 driver::Context<'scope, 'd>,
152 scope::Scope<'scope, 'd>,
153 ) -> R,
154 ) -> R {
155 let state = &mut *self.state;
156 let ctx = driver::Context::new(&mut state.local);
157 run(&mut state.token, ctx, scope::Scope::new(&mut state.work))
158 }
159
160 pub fn with_driver<R>(
162 &mut self,
163 run: impl for<'scope> FnOnce(driver::Context<'scope, 'd>, scope::Scope<'scope, 'd>) -> R,
164 ) -> R {
165 let state = &mut *self.state;
166 let ctx = driver::Context::new(&mut state.local);
167 run(ctx, scope::Scope::new(&mut state.work))
168 }
169
170 pub fn driver_ref(&self) -> driver::Reference<'d> {
171 self.state.local.driver
172 }
173
174 pub fn try_boot(&self) -> Result<(), Busy> {
177 if self.state.local.flights.is_pending() {
178 Err(Busy)
179 } else {
180 Ok(())
181 }
182 }
183
184 pub fn quiesce(&mut self) {
188 let state = &mut *self.state;
189 let ctx = driver::Context::new(&mut state.local);
190 Final::suspend(ctx).resume()
191 }
192
193 #[doc(hidden)]
196 pub fn finish<R>(
197 &mut self,
198 forced: bool,
199 run: impl for<'finish> FnOnce(
200 &mut brand::Token<brand::Identity<'d>>,
201 &mut Finish<'finish, 'd>,
202 ) -> R,
203 ) -> R {
204 let state = &mut *self.state;
205 let ctx = driver::Context::new(&mut state.local);
206 let last = Final::suspend(ctx);
207 let mut finish = Finish::new(last, forced);
208 let output = run(&mut state.token, &mut finish);
209 finish.resume();
210 output
211 }
212}
213
214impl<'a> Lease<'a> {
215 pub(crate) fn take(driver: pin::Pin<&'a mut driver::Driver>) -> Self {
216 Self { driver }
217 }
218
219 fn run_with<S, Q: ?Sized, O>(
220 self,
221 plan: S,
222 source: &domain::Source<Q>,
223 op: O,
224 report: &mut dyn Observe,
225 ) -> O::Output
226 where
227 S: storage::Direct,
228 O: Operation<S, Q>,
229 {
230 self.scope(
231 source,
232 Direct {
233 plan,
234 operation: op,
235 },
236 report,
237 )
238 }
239
240 fn try_run_with<S, Q: ?Sized, O>(
241 self,
242 plan: S,
243 source: &domain::Source<Q>,
244 op: O,
245 report: &mut dyn Observe,
246 ) -> Result<O::Output, domain::Rejected<S::Error, O>>
247 where
248 S: storage::Build,
249 O: Operation<S, Q>,
250 {
251 self.scope(
252 source,
253 Build {
254 plan,
255 operation: op,
256 },
257 report,
258 )
259 }
260
261 fn try_create<S, Q: ?Sized, O>(
262 self,
263 plan: S,
264 source: &domain::Source<Q>,
265 op: O,
266 report: &mut dyn Observe,
267 ) -> Result<O::Output, domain::Rejected<S::Error, O>>
268 where
269 S: storage::Create,
270 O: Operation<S, Q>,
271 {
272 self.scope(
273 source,
274 Create {
275 plan,
276 operation: op,
277 },
278 report,
279 )
280 }
281
282 fn run_scope<A, Q: ?Sized, O>(
283 self,
284 arenas: A,
285 source: &domain::Source<Q>,
286 op: O,
287 report: &mut dyn Observe,
288 ) -> O::Output
289 where
290 A: buffer::raw::Arenas,
291 O: Operation<storage::Scope<A>, Q>,
292 {
293 let runtime = &mut self.driver.get_mut().runtime;
294 let (report, recover) = report.split();
295 let root = Root {
296 flights: &mut runtime.flights,
297 resident: &mut runtime.resident,
298 source,
299 report,
300 recover,
301 };
302 runtime.shared.run(
303 pin::pin!((root, arenas)),
304 runtime.shared.context().buffer().layout().0.accounts(),
305 &mut runtime.backend,
306 Provided(op),
307 )
308 }
309
310 fn scope<'b, Q: ?Sized, O>(
311 self,
312 source: &'b domain::Source<Q>,
313 op: O,
314 report: &'b mut dyn Observe,
315 ) -> O::Output
316 where
317 'a: 'b,
318 O: fixed::Operation<Root<'b, Q>, driver::Buffer, driver::Shared, Terminal = crate::Engine>,
319 {
320 let runtime = &mut self.driver.get_mut().runtime;
321 let (report, recover) = report.split();
322 let root = Root {
323 flights: &mut runtime.flights,
324 resident: &mut runtime.resident,
325 source,
326 report,
327 recover,
328 };
329 runtime.shared.run(
330 pin::pin!(root),
331 runtime.shared.context().buffer().layout().0.accounts(),
332 &mut runtime.backend,
333 op,
334 )
335 }
336}
337
338const _: () = {
339 assert!(mem::size_of::<Scope<'static, 'static>>() == mem::size_of::<&mut ()>());
340 assert!(mem::align_of::<Scope<'static, 'static>>() == mem::align_of::<&mut ()>());
341};
342
343struct Root<'a, Q: ?Sized> {
344 flights: &'a mut flight::Arena,
345 resident: &'a mut resident::Arena,
346 source: &'a domain::Source<Q>,
347 report: &'a mut dyn FnMut(io::Reclaimed),
348 recover: &'a dyn Recover,
349}
350
351impl<Q: ?Sized> Root<'_, Q> {
352 fn enter<'d>(
353 &'d mut self,
354 shared: provided::Root<'d, driver::Buffer, driver::Shared, ()>,
355 token: brand::Token<brand::Identity<'d>>,
356 regions: (
357 region::Token<region::Identity<'d>>,
358 region::Token<region::Identity<'d, 1>>,
359 ),
360 backend: fixed::Loan<'d, Engine>,
361 ) -> (State<'d>, &'d Q) {
362 let alloc = self.resident.enter(®ions.0);
363 let local = Local {
364 driver: driver::Reference::new(shared),
365 backend,
366 retry: false,
367 flights: &mut *self.flights,
368 resident: alloc,
369 routes: Registry::new(),
370 region: regions,
371 lifecycle: Lifecycle {
372 source: self.source.descriptor(),
373 resuming: false,
374 pending: false,
375 report: &mut *self.report,
376 recover: self.recover,
377 },
378 };
379 let state = State::new(local, token);
380 (state, &self.source.value)
381 }
382}
383
384#[must_use]
386pub struct Install<'a, 'd> {
387 owner: marker::PhantomData<(&'a mut raw::Anchor<'a>, ThreadBound)>,
388 _driver: driver::Invariant<'d>,
389}
390
391impl<'a, 'd> Install<'a, 'd> {
392 pub fn new<T: raw::Root<'a>>(root: T, driver: driver::Reference<'d>) -> Self {
394 Self {
395 owner: root.anchor().owner(),
396 _driver: driver.brand,
397 }
398 }
399}
400
401const _: () = {
402 assert!(mem::size_of::<Install<'static, 'static>>() == 0);
403 assert!(mem::align_of::<Install<'static, 'static>>() == 1);
404};