Skip to main content

dope_core/io/socket/install/
slot.rs

1use std::mem;
2
3use o3::mem::{Lease, Return, lease::Open};
4
5use crate::{
6    driver,
7    io::fd::{domain, identity},
8};
9
10/// Exact reason a standalone fixed-file slot could not be reserved.
11#[derive(Clone, Copy, Debug, PartialEq, Eq)]
12pub enum Error {
13    Capacity { available: u32 },
14    Retiring { available: u32 },
15}
16
17#[must_use = "a fixed-file slot reservation must be installed or returned"]
18pub(crate) struct Reserved<'d> {
19    inner: Lease<Release<'d>, Open>,
20}
21
22struct Release<'d> {
23    driver: driver::Reference<'d>,
24}
25
26impl<'d> Return for Release<'d> {
27    type Item = domain::Solo<identity::Identity<'d>>;
28
29    fn return_item(self, slot: Self::Item) {
30        let (identity, solo) = slot.release();
31        let domain = self.driver.descriptors().domain();
32        domain.release(identity);
33        domain::Outbound::from(domain).release_one(solo);
34    }
35}
36
37impl<'d> Reserved<'d> {
38    pub(crate) fn try_new(driver: driver::Reference<'d>) -> Result<Self, Error> {
39        let solo = domain::Outbound::from(driver.descriptors().domain()).try_reserve()?;
40        Ok(Self {
41            inner: Lease::open(Release { driver }, solo),
42        })
43    }
44
45    pub(crate) fn slot(&self) -> &domain::Solo<identity::Identity<'d>> {
46        self.inner.item()
47    }
48
49    pub(crate) fn commit(self) -> (driver::Reference<'d>, domain::Solo<identity::Identity<'d>>) {
50        let (release, slot) = self.inner.into_parts();
51        (release.driver, slot)
52    }
53}
54
55const _: () = {
56    assert!(mem::size_of::<Result<Reserved<'static>, Error>>() == 2 * mem::size_of::<usize>());
57    assert!(mem::size_of::<Reserved<'static>>() == 2 * mem::size_of::<usize>());
58    assert!(mem::align_of::<Reserved<'static>>() == mem::align_of::<usize>());
59};