Skip to main content

dope_runtime/topology/lending/raw/
mod.rs

1use std::{marker, mem, pin};
2
3use dope_core::driver;
4
5mod bound;
6mod forward;
7mod owner;
8mod project;
9mod resume;
10
11pub use bound::Bound;
12pub use owner::Owner;
13
14/// Lifecycle storage borrowing the exact pinned provider.
15pub(crate) type Borrowed<'a, T> = Owner<pin::Pin<&'a mut T>, T>;
16pub use project::Project;
17pub use resume::Resume;
18
19// SAFETY: the owned pair forwards each lifecycle operation to both exact pinned
20// roots. Each root independently permits resume after stopped native quiescence;
21// the pair adds no operations or cleanup awaiting dispatch between them.
22unsafe impl<'d, A, B> Resume<'d> for crate::client::Pair<'d, A, B>
23where
24    A: crate::topology::lending::Root<'d> + Resume<'d>,
25    B: crate::topology::lending::Root<'d> + Resume<'d>,
26{
27}
28
29/// Operational ordering remains identical to an ordinary head-first application.
30#[pin_project::pin_project]
31#[derive(dope_gen::Application)]
32#[dispatcher(core = ::dope_core, manifold = crate, runtime = crate, driver = 'd)]
33pub struct Pair<'app, 'd, H, T> {
34    #[dispatcher(state)]
35    driver: marker::PhantomData<driver::Reference<'d>>,
36    #[pin]
37    #[app]
38    head: Borrowed<'app, H>,
39    #[pin]
40    #[app]
41    #[drain]
42    tail: Owner<mem::ManuallyDrop<T>, T>,
43}
44
45impl<'app, 'd, H, T> Pair<'app, 'd, H, T> {
46    pub(super) const fn new(head: pin::Pin<&'app mut H>, tail: T) -> Self {
47        Self {
48            driver: marker::PhantomData,
49            head: Owner::new(head),
50            tail: Owner::new(mem::ManuallyDrop::new(tail)),
51        }
52    }
53
54    pub(super) fn tail(self: pin::Pin<&Self>) -> pin::Pin<&T> {
55        Project::shared(self.project_ref().tail)
56    }
57}