Skip to main content

dope_core/io/
fd.rs

1use std::fmt::{Debug, Formatter, Result};
2use std::marker::PhantomData;
3use std::mem::ManuallyDrop;
4
5use o3::marker::ThreadBound;
6
7use crate::backend::Backend;
8use crate::driver::DriverRef;
9
10#[derive(Clone, Copy, Debug)]
11pub struct FdSlot(u32, ThreadBound);
12
13impl FdSlot {
14    pub fn new(index: u32) -> Self {
15        Self(index, ThreadBound::NEW)
16    }
17
18    pub fn raw(self) -> u32 {
19        self.0
20    }
21}
22
23pub struct Fd<'d> {
24    slot: FdSlot,
25    driver: DriverRef<'d>,
26}
27
28pub struct FdGuard<'a, 'd> {
29    backend: &'a mut Backend,
30    slot: FdSlot,
31    driver: DriverRef<'d>,
32    _invariant: PhantomData<fn(&'d ()) -> &'d ()>,
33}
34
35impl Debug for Fd<'_> {
36    fn fmt(&self, formatter: &mut Formatter<'_>) -> Result {
37        formatter.debug_tuple("Fd").field(&self.slot.0).finish()
38    }
39}
40
41impl<'d> Fd<'d> {
42    /// # Safety
43    /// `slot` must be reserved from `driver` and uniquely owned.
44    #[inline]
45    pub unsafe fn from_raw_slot(slot: FdSlot, driver: DriverRef<'d>) -> Self {
46        Self { slot, driver }
47    }
48
49    pub fn slot(&self) -> FdSlot {
50        self.slot
51    }
52
53    #[inline]
54    pub fn index(&self) -> u32 {
55        self.slot.0
56    }
57
58    pub fn driver(&self) -> DriverRef<'d> {
59        self.driver
60    }
61
62    pub(crate) fn into_parts(self) -> (FdSlot, DriverRef<'d>) {
63        (self.slot, self.driver)
64    }
65}
66
67impl<'a, 'd> FdGuard<'a, 'd> {
68    pub(crate) fn new(backend: &'a mut Backend, slot: FdSlot, driver: DriverRef<'d>) -> Self {
69        Self {
70            backend,
71            slot,
72            driver,
73            _invariant: PhantomData,
74        }
75    }
76
77    pub fn slot(&self) -> FdSlot {
78        self.slot
79    }
80
81    pub fn persist(self) -> Fd<'d> {
82        let this = ManuallyDrop::new(self);
83        Fd {
84            slot: this.slot,
85            driver: this.driver,
86        }
87    }
88}
89
90impl Drop for FdGuard<'_, '_> {
91    fn drop(&mut self) {
92        self.backend.close_fd(self.slot);
93    }
94}