dope_core/driver/ops/access/files/
mod.rs1use std::{cell, io};
2
3use crate::{
4 backend::fixed,
5 driver::{self, route, settings},
6 io::fd::handles,
7};
8
9pub(super) mod leases;
10
11pub(super) struct State {
12 pub(super) leases: cell::RefCell<leases::Leases>,
13 accept_slots: usize,
14 outbound_slots: usize,
15}
16
17impl State {
18 pub(super) fn try_new(layout: settings::FileSlots) -> io::Result<Self> {
19 Ok(Self {
20 leases: cell::RefCell::new(leases::Leases::try_new(layout)?),
21 accept_slots: layout.accept_capacity().get(),
22 outbound_slots: layout.outbound() as usize,
23 })
24 }
25}
26
27#[derive(Clone, Copy)]
28#[repr(transparent)]
29pub struct Files<'d>(driver::Reference<'d>);
30
31impl<'d> Files<'d> {
32 pub(in crate::driver) const fn new(driver: driver::Reference<'d>) -> Self {
33 Self(driver)
34 }
35
36 pub(crate) fn accept_capacity(self) -> usize {
37 self.0.shared.files.accept_slots
38 }
39
40 pub(crate) fn outbound_capacity(self) -> usize {
41 self.0.shared.files.outbound_slots
42 }
43
44 pub(crate) fn fixed_owner(self, slot: handles::FixedSlot) -> driver::FixedOwner {
45 if slot.raw() < self.0.shared.files.accept_slots as u32 {
46 return driver::FixedOwner::Accepted;
47 }
48 match self.0.shared.files.leases.borrow().owner(slot) {
49 Some(owner) => driver::FixedOwner::Outbound(owner),
50 None => driver::FixedOwner::Reserved,
51 }
52 }
53
54 pub(crate) fn track_outbound_slots<const ID: u8>(
55 self,
56 slots: fixed::Reservation<'d>,
57 ) -> Result<driver::OutboundKey, fixed::Reservation<'d>> {
58 self.0.shared.files.leases.borrow_mut().insert::<ID>(slots)
59 }
60
61 pub(crate) fn has_outbound_route<const ID: u8>(self) -> bool {
62 driver::OutboundKey::for_route::<ID>()
63 .is_some_and(|key| self.0.shared.files.leases.borrow().contains(key))
64 }
65
66 pub(crate) fn acquire_outbound_descriptor(
67 self,
68 key: driver::OutboundKey,
69 local: route::SlotIndex,
70 ) -> Option<handles::FixedSlot> {
71 self.0
72 .shared
73 .files
74 .leases
75 .borrow_mut()
76 .acquire_descriptor(key, local)
77 }
78
79 pub(crate) fn outbound_physical_index(
80 self,
81 key: driver::OutboundKey,
82 local: route::SlotIndex,
83 ) -> Option<u32> {
84 self.0
85 .shared
86 .files
87 .leases
88 .borrow()
89 .physical_index(key, local)
90 }
91
92 pub(crate) fn outbound_slot_for_target(
93 self,
94 target: route::Token,
95 ) -> Option<handles::FixedSlot> {
96 let key = driver::OutboundKey::from_raw(u32::from(target.route()))?;
97 self.0
98 .shared
99 .files
100 .leases
101 .borrow()
102 .physical_slot(key, target.slot())
103 }
104
105 pub(crate) fn has_retiring_outbound(self) -> bool {
106 self.0.shared.files.leases.borrow().has_retiring()
107 }
108
109 pub(crate) fn map_fixed_allocation_error(self, error: io::Error) -> io::Error {
110 if error.kind() == io::ErrorKind::OutOfMemory && self.has_retiring_outbound() {
111 io::Error::new(
112 io::ErrorKind::WouldBlock,
113 "dope: fixed-file slots are still retiring",
114 )
115 } else {
116 error
117 }
118 }
119}
120
121const _: () = assert!(
122 std::mem::size_of::<Files<'static>>() == std::mem::size_of::<driver::Reference<'static>>()
123);