dope_core/driver/ops/access/
maintenance.rs1use std::io;
2
3use crate::{
4 backend::fixed,
5 driver::{self, schedule::ready, settings, storage::retirements},
6 io::fd::handles,
7};
8
9pub(super) struct State {
10 retirements: retirements::Queue,
11}
12
13impl State {
14 pub(super) fn try_new(file_slots: settings::FileSlots) -> io::Result<Self> {
15 Ok(Self {
16 retirements: retirements::Queue::try_new(file_slots)?,
17 })
18 }
19}
20
21#[derive(Clone, Copy)]
22#[repr(transparent)]
23pub struct Maintenance<'d>(driver::Reference<'d>);
24
25impl<'d> Maintenance<'d> {
26 pub(in crate::driver) const fn new(driver: driver::Reference<'d>) -> Self {
27 Self(driver)
28 }
29
30 pub(crate) fn has_deferred_maintenance(self) -> bool {
31 !self.0.shared.receive.returned.is_empty()
32 || !self.0.shared.maintenance.retirements.is_empty()
33 }
34
35 pub(crate) fn return_buffer(self, buffer: driver::Buffer) {
36 self.0.shared.receive.returned.push(buffer);
37 }
38
39 pub(crate) fn pop_returned_buffer(self) -> Option<driver::Buffer> {
40 self.0.shared.receive.returned.pop()
41 }
42
43 pub(crate) fn defer_route(self, id: u8) {
44 self.0
45 .shared
46 .maintenance
47 .retirements
48 .push(retirements::Record::Route(id));
49 }
50
51 pub(crate) fn defer_descriptor(
52 self,
53 slot: handles::FixedSlot,
54 outbound: Option<driver::OutboundKey>,
55 ) {
56 self.0
57 .shared
58 .maintenance
59 .retirements
60 .push(retirements::Record::Descriptor { slot, outbound });
61 }
62
63 pub(crate) fn defer_fixed_slot(self, slot: fixed::Retirement<'d>) {
64 self.0
65 .shared
66 .maintenance
67 .retirements
68 .push(retirements::Record::Retire(slot));
69 }
70
71 pub(crate) fn defer_outbound_slots(self, slots: driver::RetiredSlots<'d>) {
72 self.0
73 .shared
74 .maintenance
75 .retirements
76 .push(retirements::Record::OutboundSlots { slots });
77 }
78
79 pub(crate) fn defer_close(self, close: driver::Close<'d>) {
80 self.0
81 .shared
82 .maintenance
83 .retirements
84 .push(retirements::Record::Close {
85 slot: close.into_slot(),
86 });
87 }
88
89 pub(in crate::driver) fn pop_deferred_retirement(self) -> Option<retirements::Record<'d>> {
90 self.0.shared.maintenance.retirements.pop(self.0)
91 }
92
93 pub(crate) fn retire_fixed_release(self, released: ready::FixedRelease<'d>) {
94 let slot = released.slot();
95 match self.0.files().fixed_owner(slot) {
96 driver::FixedOwner::Accepted => self.defer_descriptor(released.into_slot(), None),
97 driver::FixedOwner::Reserved => {
98 self.defer_fixed_slot(fixed::Retirement::from_release(released));
99 }
100 driver::FixedOwner::Outbound(outbound) => {
101 if !self.0.outbound().is_unopened(outbound, slot) {
102 self.defer_descriptor(released.into_slot(), Some(outbound));
103 return;
104 }
105 if let Some(slots) = self
106 .0
107 .outbound()
108 .release_outbound_slot(outbound, released.into_slot())
109 {
110 self.defer_outbound_slots(slots);
111 }
112 }
113 }
114 }
115}
116
117const _: () = assert!(
118 std::mem::size_of::<Maintenance<'static>>()
119 == std::mem::size_of::<driver::Reference<'static>>()
120);