Skip to main content

dope_core/driver/ops/access/files/
mod.rs

1use 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);