base_scheduler/
buffer_lease.rs1use crate::{FrozenBuffer, IoBuf, IoBufMut, heap_buffer_pool::Slab};
5use std::{ops::Range, ptr::NonNull, sync::atomic::Ordering};
6
7pub struct BufferLease {
9 slab: Option<NonNull<Slab>>,
10 index: usize,
11 length: usize,
12}
13
14impl BufferLease {
15 pub(crate) fn new(slab: NonNull<Slab>, index: usize, length: usize) -> Self {
16 Self {
17 slab: Some(slab),
18 index,
19 length,
20 }
21 }
22
23 pub fn truncate(&mut self, length: usize) {
25 assert!(length <= self.length, "buffer length out of bounds");
26 self.length = length;
27 }
28
29 pub fn freeze(mut self) -> FrozenBuffer {
31 let slab = self.slab.take().unwrap();
32 unsafe { slab.as_ref() }.slots[self.index]
34 .readers
35 .store(1, Ordering::Relaxed);
36 FrozenBuffer::new(
37 slab,
38 self.index,
39 Range {
40 start: 0,
41 end: self.length,
42 },
43 )
44 }
45}
46
47impl AsRef<[u8]> for BufferLease {
48 fn as_ref(&self) -> &[u8] {
49 let slab = unsafe { self.slab.unwrap().as_ref() };
51 unsafe { std::slice::from_raw_parts(slab.pointer(self.index), self.length) }
52 }
53}
54impl AsMut<[u8]> for BufferLease {
55 fn as_mut(&mut self) -> &mut [u8] {
56 let slab = unsafe { self.slab.unwrap().as_ref() };
58 unsafe { std::slice::from_raw_parts_mut(slab.pointer(self.index), self.length) }
59 }
60}
61impl Drop for BufferLease {
62 fn drop(&mut self) {
63 if let Some(slab) = self.slab.take() {
64 unsafe { Slab::release(slab, self.index) };
66 }
67 }
68}
69
70unsafe impl IoBuf for BufferLease {}
72unsafe impl IoBufMut for BufferLease {}
73
74unsafe impl Send for BufferLease {}
76unsafe impl Sync for BufferLease {}
77
78impl std::fmt::Debug for BufferLease {
79 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80 formatter
81 .debug_struct("BufferLease")
82 .field("length", &self.length)
83 .finish_non_exhaustive()
84 }
85}
86
87impl crate::ReceiveBuffer for BufferLease {
88 type Frozen = FrozenBuffer;
89 fn truncate(&mut self, length: usize) {
90 BufferLease::truncate(self, length);
91 }
92 fn freeze(self) -> FrozenBuffer {
93 BufferLease::freeze(self)
94 }
95}