Skip to main content

cartel_sqlite/engine/conn/
raw.rs

1use crate::{
2    api, catalogs,
3    conn::{
4        Installed,
5        phase::{Live, Phase},
6    },
7    runtime,
8};
9use api::stmt;
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    /// # Safety
23    /// Storage is an uninitialized, aligned LAYOUT partition retained for 'local.
24    /// The consumed database admission grants its only initialization authority.
25    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        // SAFETY: this affine vacancy owns the admitted storage's sole initialization.
34        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        // SAFETY: client loans ended before this unique owner is destroyed. Local
45        // retains the backing allocation, including when this owner is forgotten.
46        unsafe { self.phase.as_ptr().drop_in_place() };
47    }
48}
49
50// SAFETY: SQLite owns no driver routes or asynchronous native requests. Its SQL
51// and VFS calls finish synchronously. Retry alarms retain resident timer leases;
52// cleanup checks their absolute deadlines and clears them without native dispatch.
53// The pinned connection and allocator remain owned through release and finish.
54unsafe impl<'local, 'd: 'local, I: catalogs::Catalog> lending::raw::Resume<'d>
55    for Installed<'local, 'd, I>
56{
57}
58
59impl<'local, 'd: 'local, I: catalogs::Catalog> executor::raw::Layout<'d>
60    for Installed<'local, 'd, I>
61{
62    type ParkPlan = ();
63}
64
65unsafe impl<'local, 'd: 'local, I: catalogs::Catalog> executor::raw::App<'d>
66    for Installed<'local, 'd, I>
67{
68    const ROUTES: settings::Routes = settings::Routes::EMPTY;
69    const COORDS: usize = 1;
70
71    fn select_park() -> Option<Self::ParkPlan> {
72        Some(())
73    }
74
75    fn released(
76        mut released: executor::raw::Released<'_, Self>,
77    ) -> executor::raw::Released<'_, Self> {
78        let app = released.owner();
79        let conn = app.as_ref().get_ref();
80        // SAFETY: Released ends all client access to this exact pinned owner,
81        // including loans whose guards were forgotten without running Drop.
82        unsafe { &mut *conn.phase.as_ptr() }.released();
83        released
84    }
85
86    fn shutdown<'app, 'turn, 'driver, 'owner>(
87        shutdown: executor::raw::Shutdown<'app, 'turn, 'driver, 'owner, 'd, Self>,
88    ) -> executor::raw::Shutdown<'app, 'turn, 'driver, 'owner, 'd, Self>
89    where
90        'd: 'owner,
91    {
92        let (app, turn, driver) = shutdown.into_parts();
93        let conn = app.as_ref().get_ref();
94        // SAFETY: shared phase access preserves any dependent client's state borrow.
95        unsafe { &*conn.phase.as_ptr() }.stop();
96        executor::raw::Shutdown::new(app, turn, driver)
97    }
98
99    fn finish<'app, 'finish, 'owner, 'epoch>(
100        finish: executor::raw::Finish<'app, 'finish, 'owner, 'epoch, 'd, Self>,
101    ) -> executor::raw::Finish<'app, 'finish, 'owner, 'epoch, 'd, Self> {
102        let (app, install, finish) = finish.into_parts();
103        if finish.is_forced() {
104            let conn = app.as_ref().get_ref();
105            // SAFETY: all client borrows ended before this final pinned application access.
106            unsafe { &mut *conn.phase.as_ptr() }.force();
107        }
108        executor::raw::Finish::new(app, install, finish)
109    }
110
111    fn progress(
112        app: pin::Pin<&Self>,
113        _: executor::raw::Progress<'_, '_, 'd>,
114    ) -> schedule::Progress<'d> {
115        // SAFETY: progress only reads the phase; Live excludes active client state borrows.
116        unsafe { &*app.get_ref().phase.as_ptr() }.progress::<false>()
117    }
118
119    fn stopping(
120        app: pin::Pin<&Self>,
121        _: executor::raw::Progress<'_, '_, 'd>,
122    ) -> schedule::Progress<'d> {
123        // SAFETY: stopping only reads the phase; Live excludes active client state borrows.
124        unsafe { &*app.get_ref().phase.as_ptr() }.progress::<true>()
125    }
126
127    /// # Safety
128    /// The root, prepared plan, and park authority belong to this installed owner.
129    unsafe fn park<'app, 'driver, 'turn, 'root>(
130        app: pin::Pin<&'app mut Self>,
131        (): &mut Self::ParkPlan,
132        mut park: executor::raw::Park<'driver, 'turn, 'root, 'd>,
133    ) where
134        'd: 'driver + 'turn + 'root,
135    {
136        let conn = app.as_ref().get_ref();
137        // SAFETY: the phase remains pinned, and shared access preserves client state borrows.
138        let phase = unsafe { &*conn.phase.as_ptr() };
139        if let Phase::Live(live) = phase
140            && live.borrow.get().is_borrowed()
141        {
142            return;
143        }
144        // SAFETY: phase admission excludes client borrows, and park excludes reentry.
145        let phase = unsafe { &mut *conn.phase.as_ptr() };
146        loop {
147            let (state, plan) = match phase {
148                Phase::Live(live) => {
149                    // SAFETY: the vacant live phase excludes all mutable client state borrows.
150                    let state = unsafe { &mut *live.state.get() };
151                    let plan = state.maintenance(park.now());
152                    (state, plan)
153                }
154                Phase::Closing(state) => {
155                    let plan = state.maintenance(park.now());
156                    if matches!(plan, api::Plan::Idle) {
157                        phase.retire();
158                        continue;
159                    }
160                    (state, plan)
161                }
162                Phase::Retiring(retiring) => {
163                    if matches!(retiring.inventory(), stmt::Inventory::Empty) {
164                        break;
165                    }
166                    if park.next_step().is_none() {
167                        break;
168                    }
169                    retiring.retire_one();
170                    continue;
171                }
172                Phase::Empty => break,
173            };
174            match plan {
175                api::Plan::Idle | api::Plan::Delayed => break,
176                api::Plan::Ready => {}
177            }
178            let Some(step) = park.next_step() else {
179                break;
180            };
181            if state.maintain(step.now()).is_pending() {
182                break;
183            }
184        }
185    }
186}