Skip to main content

dope_sys/engine/life/
mod.rs

1mod error;
2mod step;
3
4use std::{ops::ControlFlow, os::fd::BorrowedFd};
5
6pub use error::Error;
7pub use step::Step;
8
9use crate::{engine, probe::Stopped};
10
11pub(super) type Retirement<T, R> = Result<
12    T,
13    Stopped<
14        R,
15        Error<<<R as Resolver>::Backend as engine::raw::Poll>::Error, <R as Resolver>::Fault>,
16    >,
17>;
18
19/// A host's exact driver root retains all completion and retirement authority.
20pub trait Resolver: Sized {
21    type Backend: engine::raw::Poll;
22    type Fault: Copy;
23
24    fn backend(&mut self) -> &mut Self::Backend;
25    fn retire_one(&mut self) -> Step;
26    /// Retires every currently admissible descriptor, stopping at backpressure.
27    fn retire(&mut self) {
28        while let Step::Advanced = self.retire_one() {}
29    }
30    fn has_pending(&self) -> bool;
31    fn has_flights(&self) -> bool;
32    fn has_inflight(&self) -> bool;
33}
34
35/// A phase whose completions may only reclaim their registered owners.
36pub trait Reclaim: Resolver {
37    fn reclaim(self) -> Result<ControlFlow<Self, Self>, Stopped<Self, Self::Fault>>;
38    /// Reports the exact completion fault once, returning its owner to drain.
39    fn fault(failure: Stopped<Self, Self::Fault>) -> Self;
40    /// Reports a native retirement failure while its retry owner remains retained.
41    fn reactor(&mut self, failure: <Self::Backend as engine::raw::Poll>::Error);
42
43    /// Consumes only the currently acquired completion batch. Every fault is
44    /// reported before the first fault and the exact remaining owner return.
45    fn drain(mut self) -> Result<Self, Stopped<Self, Self::Fault>> {
46        let mut first = None;
47        let state = loop {
48            match self.reclaim() {
49                Ok(ControlFlow::Continue(state)) => self = state,
50                Ok(ControlFlow::Break(state)) => break state,
51                Err(failure) => {
52                    first.get_or_insert(failure.cause);
53                    self = Self::fault(failure);
54                }
55            }
56        };
57        match first {
58            None => Ok(state),
59            Some(cause) => Err(Stopped { state, cause }),
60        }
61    }
62}
63
64/// The terminal host state borrowed alongside its exact native backend.
65pub trait Terminal {
66    fn has_flights(&self) -> bool;
67    fn has_inflight(&self) -> bool;
68    fn has_pending(&self) -> bool;
69    fn source(&self) -> Option<BorrowedFd<'_>>;
70}
71
72/// Lends the disjoint backend and host state for final retirement and resumption.
73pub trait Resume: Reclaim {
74    type Terminal<'s>: Terminal
75    where
76        Self: 's;
77
78    fn terminal(&mut self) -> (&mut Self::Backend, Self::Terminal<'_>);
79}
80
81/// Consumes an active phase before final descriptor retirement.
82pub trait Close: Resolver {
83    type Closing: Reclaim<Backend = Self::Backend, Fault = Self::Fault>;
84
85    fn into_closing(self) -> Self::Closing;
86}
87
88/// Consumes running authority before canceling outstanding kernel operations.
89pub trait Cancel: Close {
90    type Cancelling: Reclaim<Backend = Self::Backend, Fault = Self::Fault>
91        + Close<Closing = Self::Closing>;
92
93    fn cancel(self) -> Self::Cancelling;
94}
95
96/// Native terminal census and retirement retain the exact resolved owner.
97/// Implementations issue this authority only after the kernel no longer uses
98/// that owner's borrowed request storage or pending retirement resources.
99pub trait Quiesced {
100    type Resolver: Reclaim;
101
102    fn into_inner(self) -> Self::Resolver;
103}
104
105/// Native final retirement after the host has closed admission.
106pub trait Finish<'a, R>
107where
108    R: Reclaim + 'a,
109    <R::Backend as engine::raw::Poll>::Context: 'a,
110{
111    type Quiesced: Quiesced<Resolver = R>;
112
113    fn try_finish(resolver: R) -> Retirement<Self::Quiesced, R>;
114}
115
116/// Native cancellation and final retirement consume the running host phase.
117pub trait Quiesce<'a, R>
118where
119    R: Cancel + 'a,
120    <R::Backend as engine::raw::Poll>::Context: 'a,
121{
122    type Quiesced: Quiesced<Resolver = R::Closing>;
123
124    fn try_quiesce(resolver: R) -> Retirement<Self::Quiesced, R::Closing>;
125}