feox_server/io/
buffer_pool.rs1use bytes::{Bytes, BytesMut};
2use parking_lot::Mutex;
3use std::collections::VecDeque;
4use std::sync::Arc;
5
6pub struct BufferPool {
8 buffers: Vec<BufferSlot>,
10
11 free_list: Arc<Mutex<VecDeque<usize>>>,
13
14 buffer_size: usize,
16}
17
18struct BufferSlot {
19 data: Vec<u8>,
20 in_use: Arc<Mutex<bool>>,
21}
22
23impl BufferPool {
24 pub fn new(num_buffers: usize, buffer_size: usize) -> Self {
25 let mut buffers = Vec::with_capacity(num_buffers);
26 let mut free_list = VecDeque::with_capacity(num_buffers);
27
28 for i in 0..num_buffers {
29 let data = vec![0u8; buffer_size];
31
32 buffers.push(BufferSlot {
33 data,
34 in_use: Arc::new(Mutex::new(false)),
35 });
36
37 free_list.push_back(i);
38 }
39
40 Self {
41 buffers,
42 free_list: Arc::new(Mutex::new(free_list)),
43 buffer_size,
44 }
45 }
46
47 pub fn get_buffer(&self) -> Option<BufferHandle> {
49 let mut free_list = self.free_list.lock();
50
51 if let Some(index) = free_list.pop_front() {
52 let slot = &self.buffers[index];
53 *slot.in_use.lock() = true;
54
55 Some(BufferHandle {
56 index,
57 data: slot.data.as_ptr(),
58 len: self.buffer_size,
59 pool: self as *const BufferPool,
60 })
61 } else {
62 None
63 }
64 }
65
66 fn return_buffer(&self, index: usize) {
68 if index < self.buffers.len() {
69 let slot = &self.buffers[index];
70 *slot.in_use.lock() = false;
71 self.free_list.lock().push_back(index);
72 }
73 }
74
75 pub fn get_buffer_mut(&self) -> Option<BufferHandleMut> {
77 let mut free_list = self.free_list.lock();
78
79 if let Some(index) = free_list.pop_front() {
80 let slot = &self.buffers[index];
81 *slot.in_use.lock() = true;
82
83 Some(BufferHandleMut {
84 index,
85 buffer: BytesMut::from(&slot.data[..]),
86 pool: self as *const BufferPool,
87 })
88 } else {
89 None
90 }
91 }
92
93 pub fn buffer_to_bytes(&self, index: usize, len: usize) -> Option<Bytes> {
95 if index >= self.buffers.len() || len > self.buffer_size {
96 return None;
97 }
98
99 let data = &self.buffers[index].data[..len];
100 Some(Bytes::copy_from_slice(data))
101 }
102}
103
104pub struct BufferHandle {
106 index: usize,
107 data: *const u8,
108 len: usize,
109 pool: *const BufferPool,
110}
111
112impl BufferHandle {
113 pub fn index(&self) -> usize {
114 self.index
115 }
116
117 pub fn as_slice(&self) -> &[u8] {
118 unsafe { std::slice::from_raw_parts(self.data, self.len) }
119 }
120
121 pub fn as_mut_slice(&mut self) -> &mut [u8] {
122 unsafe { std::slice::from_raw_parts_mut(self.data as *mut u8, self.len) }
123 }
124}
125
126impl Drop for BufferHandle {
127 fn drop(&mut self) {
128 unsafe {
129 let pool = &*self.pool;
130 pool.return_buffer(self.index);
131 }
132 }
133}
134
135pub struct BufferHandleMut {
137 index: usize,
138 buffer: BytesMut,
139 pool: *const BufferPool,
140}
141
142impl BufferHandleMut {
143 pub fn buffer_mut(&mut self) -> &mut BytesMut {
144 &mut self.buffer
145 }
146
147 pub fn freeze(mut self) -> Bytes {
148 self.buffer.split().freeze()
149 }
150}
151
152impl Drop for BufferHandleMut {
153 fn drop(&mut self) {
154 unsafe {
155 let pool = &*self.pool;
156 pool.return_buffer(self.index);
157 }
158 }
159}
160
161unsafe impl Send for BufferHandle {}
163unsafe impl Sync for BufferHandle {}
164unsafe impl Send for BufferHandleMut {}
165unsafe impl Sync for BufferHandleMut {}