dope_session/pool/
slot.rs1use 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> {}