cartel_sqlite/engine/conn/
raw.rs1use crate::{
2 api, catalogs,
3 conn::{
4 Installed,
5 phase::{Live, Phase},
6 },
7 runtime,
8};
9use api::{stmt, work::cleanup::Status};
10use dope_core::driver::{schedule, settings};
11use dope_runtime::{executor, topology::lending};
12use std::{alloc::Layout, marker, pin, ptr};
13
14pub(crate) struct Vacant<'local, 'd: 'local, I: catalogs::Catalog> {
15 phase: ptr::NonNull<Phase<'local, 'd, I>>,
16 backing: marker::PhantomData<&'local mut Phase<'local, 'd, I>>,
17}
18
19impl<'local, 'd: 'local, I: catalogs::Catalog> Vacant<'local, 'd, I> {
20 pub(crate) const LAYOUT: Layout = Layout::new::<Phase<'local, 'd, I>>();
21
22 pub(crate) unsafe fn new(storage: &'local runtime::raw::Span) -> Self {
26 Self {
27 phase: storage.base().cast(),
28 backing: marker::PhantomData,
29 }
30 }
31
32 pub(crate) fn insert(self, state: api::State<'local, 'd, I>) -> Installed<'local, 'd, I> {
33 unsafe { self.phase.as_ptr().write(Phase::Live(Live::new(state))) };
35 Installed {
36 phase: self.phase,
37 ownership: marker::PhantomData,
38 }
39 }
40}
41
42impl<I: catalogs::Catalog> Drop for Installed<'_, '_, I> {
43 fn drop(&mut self) {
44 unsafe { self.phase.as_ptr().drop_in_place() };
47 }
48}
49
50unsafe impl<'local, 'd: 'local, I: catalogs::Catalog> lending::raw::Resume<'d>
54 for Installed<'local, 'd, I>
55{
56}
57
58impl<'local, 'd: 'local, I: catalogs::Catalog> executor::raw::Layout<'d>
59 for Installed<'local, 'd, I>
60{
61 type ParkPlan = ();
62}
63
64unsafe impl<'local, 'd: 'local, I: catalogs::Catalog> executor::raw::App<'d>
65 for Installed<'local, 'd, I>
66{
67 const ROUTES: settings::Routes = settings::Routes::EMPTY;
68 const COORDS: usize = 1;
69
70 fn select_park() -> Option<Self::ParkPlan> {
71 Some(())
72 }
73
74 fn released(
75 mut released: executor::raw::Released<'_, Self>,
76 ) -> executor::raw::Released<'_, Self> {
77 let app = released.owner();
78 let conn = app.as_ref().get_ref();
79 unsafe { &mut *conn.phase.as_ptr() }.released();
82 released
83 }
84
85 fn shutdown<'app, 'turn, 'driver>(
86 shutdown: executor::raw::Shutdown<'app, 'turn, 'driver, 'd, Self>,
87 ) -> executor::raw::Shutdown<'app, 'turn, 'driver, 'd, Self> {
88 let (app, turn, driver) = shutdown.into_parts();
89 let conn = app.as_ref().get_ref();
90 unsafe { &*conn.phase.as_ptr() }.stop();
92 executor::raw::Shutdown::new(app, turn, driver)
93 }
94
95 fn finish<'app, 'finish, 'owner, 'epoch>(
96 finish: executor::raw::Finish<'app, 'finish, 'owner, 'epoch, 'd, Self>,
97 ) -> executor::raw::Finish<'app, 'finish, 'owner, 'epoch, 'd, Self> {
98 let (app, install, finish) = finish.into_parts();
99 if finish.is_forced() {
100 let conn = app.as_ref().get_ref();
101 unsafe { &mut *conn.phase.as_ptr() }.force();
103 }
104 executor::raw::Finish::new(app, install, finish)
105 }
106
107 fn progress(
108 app: pin::Pin<&Self>,
109 _: executor::raw::Progress<'_, '_, 'd>,
110 ) -> schedule::Progress<'d> {
111 unsafe { &*app.get_ref().phase.as_ptr() }.progress::<false>()
113 }
114
115 fn stopping(
116 app: pin::Pin<&Self>,
117 _: executor::raw::Progress<'_, '_, 'd>,
118 ) -> schedule::Progress<'d> {
119 unsafe { &*app.get_ref().phase.as_ptr() }.progress::<true>()
121 }
122
123 unsafe fn park<'app, 'driver, 'turn>(
126 app: pin::Pin<&'app mut Self>,
127 (): &mut Self::ParkPlan,
128 mut park: executor::raw::Park<'driver, 'turn, 'd>,
129 ) where
130 'd: 'driver + 'turn,
131 {
132 let conn = app.as_ref().get_ref();
133 let phase = unsafe { &*conn.phase.as_ptr() };
135 if let Phase::Live(live) = phase
136 && live.borrow.get().is_borrowed()
137 {
138 return;
139 }
140 let phase = unsafe { &mut *conn.phase.as_ptr() };
142 loop {
143 let (state, pending) = match phase {
144 Phase::Live(live) => {
145 let state = unsafe { &mut *live.state.get() };
147 let pending = state.pending();
148 (state, pending)
149 }
150 Phase::Closing(state) => {
151 let pending = state.pending();
152 if matches!(pending, Status::Idle) {
153 phase.retire();
154 continue;
155 }
156 (state, pending)
157 }
158 Phase::Retiring(retiring) => {
159 if matches!(retiring.inventory(), stmt::Inventory::Empty) {
160 break;
161 }
162 if park.next_step().is_none() {
163 break;
164 }
165 retiring.retire_one();
166 continue;
167 }
168 Phase::Empty => break,
169 };
170 match pending {
171 Status::Idle => break,
172 Status::Pending => {}
173 }
174 if park.next_step().is_none() {
175 break;
176 }
177 state.cleanup();
178 }
179 }
180}