1use std::{marker, mem, ops, pin};
2
3use dope_core::{
4 driver::{retained, schedule, settings},
5 io,
6};
7use o3::base::cell::region;
8
9use super::forward;
10use crate::{executor, topology::lending};
11
12#[pin_project::pin_project]
13#[repr(transparent)]
14pub struct Owner<S, T> {
15 #[pin]
16 stored: S,
17 app: marker::PhantomData<T>,
18}
19
20impl<S, T> Owner<S, T> {
21 pub(super) const fn new(stored: S) -> Self {
22 Self {
23 stored,
24 app: marker::PhantomData,
25 }
26 }
27}
28
29unsafe impl<S: lending::raw::Project<App = T>, T> lending::raw::Project for Owner<S, T> {
31 type App = T;
32
33 fn shared(self: pin::Pin<&Self>) -> pin::Pin<&Self::App> {
34 self.project_ref().stored.shared()
35 }
36
37 fn exclusive(self: pin::Pin<&mut Self>) -> pin::Pin<&mut Self::App> {
38 self.project().stored.exclusive()
39 }
40}
41
42impl<'d, S, T> executor::raw::Layout<'d> for Owner<S, T>
43where
44 T: executor::raw::Layout<'d>,
45{
46 type ParkPlan = <T as executor::raw::Layout<'d>>::ParkPlan;
47}
48
49unsafe impl<'d, S, T> executor::raw::App<'d> for Owner<S, T>
52where
53 S: lending::raw::Project<App = T>,
54 T: executor::raw::App<'d>,
55 Self: executor::raw::Finishes<'d, Self>,
56{
57 const ROUTES: settings::Routes = T::ROUTES;
58 const WAKE_ROUTES: settings::Routes = T::WAKE_ROUTES;
59 const COORDS: usize = <T as executor::raw::App<'d>>::COORDS;
60
61 fn select_park() -> Option<Self::ParkPlan> {
62 <T as executor::raw::App<'d>>::select_park()
63 }
64
65 fn prepare_park(
66 app: pin::Pin<&Self>,
67 plan: &mut Self::ParkPlan,
68 ) -> Option<executor::raw::Count> {
69 <T as executor::raw::App<'d>>::prepare_park(lending::raw::Project::shared(app), plan)
70 }
71
72 unsafe fn park<'app, 'driver, 'turn, 'root>(
73 app: pin::Pin<&'app mut Self>,
74 plan: &mut Self::ParkPlan,
75 park: executor::raw::Park<'driver, 'turn, 'root, 'd>,
76 ) where
77 'd: 'driver + 'turn + 'root,
78 {
79 unsafe { forward::park(app, plan, park) }
81 }
82
83 unsafe fn activate<'app, 'driver, 'turn, 'root>(
84 app: pin::Pin<&'app mut Self>,
85 activate: executor::raw::Activate<'driver, 'turn, 'root, 'd>,
86 ) -> bool
87 where
88 'd: 'driver + 'turn + 'root,
89 {
90 unsafe { forward::activate(app, activate) }
92 }
93
94 fn admit(
95 app: pin::Pin<&Self>,
96 needs: &mut settings::claim::Needs,
97 ) -> Result<(), settings::errors::Claim> {
98 T::admit(lending::raw::Project::shared(app), needs)
99 }
100
101 fn released(released: executor::raw::Released<'_, Self>) -> executor::raw::Released<'_, Self> {
102 unsafe { released.visit(lending::raw::Project::exclusive) }
104 }
105
106 fn install<'app, 'owner>(
107 call: executor::raw::Install<'app, 'owner, 'd, Self>,
108 ) -> executor::raw::Install<'app, 'owner, 'd, Self> {
109 forward::install(call)
110 }
111
112 fn dispatch<'app, 'driver, 'turn, 'root>(
113 call: executor::raw::Dispatch<'app, 'driver, 'turn, 'root, 'd, Self>,
114 ) -> ops::ControlFlow<io::Event<'d>>
115 where
116 'd: 'root,
117 Self: 'root,
118 {
119 forward::dispatch(call)
120 }
121
122 fn shutdown<'app, 'turn, 'driver, 'owner>(
123 call: executor::raw::Shutdown<'app, 'turn, 'driver, 'owner, 'd, Self>,
124 ) -> executor::raw::Shutdown<'app, 'turn, 'driver, 'owner, 'd, Self>
125 where
126 'd: 'owner,
127 {
128 forward::shutdown(call)
129 }
130
131 fn finish<'app, 'finish, 'owner, 'epoch>(
132 call: executor::raw::Finish<'app, 'finish, 'owner, 'epoch, 'd, Self>,
133 ) -> executor::raw::Finish<'app, 'finish, 'owner, 'epoch, 'd, Self> {
134 <Self as executor::raw::Finishes<'d>>::call(call)
135 }
136
137 fn progress(
138 app: pin::Pin<&Self>,
139 view: executor::raw::Progress<'_, '_, 'd>,
140 ) -> schedule::Progress<'d> {
141 T::progress(lending::raw::Project::shared(app), view)
142 }
143
144 fn stopping(
145 app: pin::Pin<&Self>,
146 view: executor::raw::Progress<'_, '_, 'd>,
147 ) -> schedule::Progress<'d> {
148 T::stopping(lending::raw::Project::shared(app), view)
149 }
150}
151
152impl<'d, T> executor::raw::Finishes<'d, Self> for lending::raw::Borrowed<'_, T>
153where
154 T: executor::raw::App<'d>,
155{
156 fn call<'app, 'finish, 'owner, 'epoch>(
157 call: executor::raw::Finish<'app, 'finish, 'owner, 'epoch, 'd, Self>,
158 ) -> executor::raw::Finish<'app, 'finish, 'owner, 'epoch, 'd, Self> {
159 forward::finish(call)
160 }
161}
162
163impl<'d, T> executor::raw::Finishes<'d, Self> for Owner<mem::ManuallyDrop<T>, T>
164where
165 T: executor::raw::App<'d>,
166{
167 fn call<'app, 'finish, 'owner, 'epoch>(
168 call: executor::raw::Finish<'app, 'finish, 'owner, 'epoch, 'd, Self>,
169 ) -> executor::raw::Finish<'app, 'finish, 'owner, 'epoch, 'd, Self> {
170 let (mut app, install, finish) = forward::finish(call).into_parts();
171 unsafe { mem::ManuallyDrop::drop(app.as_mut().project().stored.get_unchecked_mut()) };
174 executor::raw::Finish::new(app, install, finish)
175 }
176}
177
178unsafe impl<'d, S, T> executor::raw::Drain<'d> for Owner<S, T>
181where
182 S: lending::raw::Project<App = T>,
183 T: executor::raw::Drain<'d>,
184 Self: executor::raw::Finishes<'d, Self>,
185{
186 fn begin(
187 self: pin::Pin<&mut Self>,
188 turn: schedule::Turn<'_, 'd>,
189 driver: &mut retained::Context<'_, '_, 'd>,
190 ) {
191 executor::raw::Drain::begin(lending::raw::Project::exclusive(self), turn, driver);
192 }
193
194 fn progress(
195 self: pin::Pin<&Self>,
196 region: ®ion::Token<region::Identity<'d>>,
197 ) -> schedule::Progress<'d> {
198 executor::raw::Drain::progress(lending::raw::Project::shared(self), region)
199 }
200
201 fn force(
202 self: pin::Pin<&mut Self>,
203 turn: schedule::Turn<'_, 'd>,
204 driver: &mut retained::Context<'_, '_, 'd>,
205 ) {
206 executor::raw::Drain::force(lending::raw::Project::exclusive(self), turn, driver);
207 }
208}