Skip to main content

dope_session/pool/
slot.rs

1use super::core::ConnIoSlot;
2use crate::CodecLayer;
3use crate::SlotGen;
4use crate::WriteBufStorage;
5use dambi::AlwaysInit;
6use dope_core::FixedFd;
7
8pub(crate) const INGRESS_BUF_CAP: usize = 8 * 1024;
9pub const WRITE_BUF_CAP: usize = 16 * 1024;
10pub(crate) const WRITE_ROOM_MIN: usize = 256;
11
12#[derive(Clone, Copy, Debug, Default)]
13pub(crate) struct ConnFlags(u8);
14
15impl ConnFlags {
16    pub(crate) const LIVE: u8 = 1 << 0;
17    pub(crate) const CLOSE_AFTER: u8 = 1 << 2;
18    pub(crate) const PARKED: u8 = 1 << 3;
19
20    #[inline]
21    pub(crate) const fn empty() -> Self {
22        Self(0)
23    }
24
25    #[inline]
26    pub(crate) const fn contains(self, bit: u8) -> bool {
27        (self.0 & bit) == bit
28    }
29
30    #[inline]
31    #[allow(dead_code)]
32    pub(crate) const fn intersects(self, mask: u8) -> bool {
33        (self.0 & mask) != 0
34    }
35
36    #[inline]
37    pub(crate) fn set(&mut self, bit: u8, on: bool) {
38        if on {
39            self.0 |= bit;
40        } else {
41            self.0 &= !bit;
42        }
43    }
44}
45
46#[repr(C, align(64))]
47pub(crate) struct Conn {
48    pub(super) fd: FixedFd,
49    pub(super) generation: SlotGen,
50    pub(super) flags: ConnFlags,
51    pub(super) write_head: u16,
52    pub(super) write_tail: u16,
53    pub(super) write_inflight_end: u16,
54    pub(super) ingress_head: u16,
55    pub(super) ingress_tail: u16,
56    pub(super) parse_phase: u8,
57    pub(super) body_needed: u32,
58    pub(super) pending_body_ptr: *const u8,
59    pub(super) pending_body_len: u32,
60    pub(super) large_inflight: u32,
61    pub(super) large_tail: u32,
62    _pad: [u8; 4],
63}
64
65const _: () = assert!(std::mem::size_of::<Conn>() == 64);
66const _: () = assert!(std::mem::align_of::<Conn>() == 64);
67
68impl Conn {
69    pub(crate) fn reset_for_reuse(&mut self) {
70        self.generation = self.generation.checked_add(1).unwrap_or(SlotGen::MIN);
71        self.flags = ConnFlags::empty();
72        self.write_head = 0;
73        self.write_tail = 0;
74        self.write_inflight_end = 0;
75        self.ingress_head = 0;
76        self.ingress_tail = 0;
77        self.parse_phase = 0;
78        self.body_needed = 0;
79        self.pending_body_ptr = std::ptr::null();
80        self.pending_body_len = 0;
81        self.large_inflight = 0;
82        self.large_tail = 0;
83    }
84}
85
86#[repr(C, align(64))]
87pub(crate) struct BufSlot<W: WriteBufStorage> {
88    pub(super) ingress_buf: [u8; INGRESS_BUF_CAP],
89    pub(super) write_buf: W,
90
91    pub(super) pending_iovs: [libc::iovec; 4],
92    pub(super) pending_msghdr: libc::msghdr,
93
94    pub(super) staged_gather_cookie: *const u8,
95}
96
97unsafe impl<W: WriteBufStorage> Send for BufSlot<W> {}
98unsafe impl<W: WriteBufStorage> Sync for BufSlot<W> {}
99
100const _: () = assert!(std::mem::align_of::<BufSlot<crate::codec::WriteBufArr>>() == 64);
101
102#[repr(C, align(64))]
103pub(crate) struct CoreSlot<L: CodecLayer, U: 'static> {
104    pub(super) conn: Conn,
105    pub(super) io: ConnIoSlot,
106    pub(super) buf: BufSlot<L::WriteBuf>,
107    pub(super) codec_state: AlwaysInit<L::ConnState>,
108    pub(super) user: AlwaysInit<U>,
109}
110
111unsafe impl<L: CodecLayer, U: 'static> Send for CoreSlot<L, U> {}
112unsafe impl<L: CodecLayer, U: 'static> Sync for CoreSlot<L, U> {}