Skip to main content

compio_driver/buffer_pool/
iour.rs

1//! The io-uring buffer pool. It is backed by a [`Vec`] of [`Vec<u8>`].
2//! The kernel selects the buffer and returns `flags`. The crate
3//! [`io_uring_buf_ring`] handles the returning of buffer on drop.
4
5use std::{
6    borrow::{Borrow, BorrowMut},
7    fmt::{Debug, Formatter},
8    io,
9    ops::{Deref, DerefMut},
10};
11
12use io_uring_buf_ring::IoUringBufRing;
13
14/// Buffer pool
15///
16/// A buffer pool to allow user no need to specify a specific buffer to do the
17/// IO operation
18pub struct BufferPool {
19    buf_ring: IoUringBufRing<Vec<u8>>,
20}
21
22impl Debug for BufferPool {
23    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
24        f.debug_struct("BufferPool").finish_non_exhaustive()
25    }
26}
27
28impl BufferPool {
29    pub(crate) fn new(buf_ring: IoUringBufRing<Vec<u8>>) -> Self {
30        Self { buf_ring }
31    }
32
33    pub(crate) fn buffer_group(&self) -> u16 {
34        self.buf_ring.buffer_group()
35    }
36
37    pub(crate) fn into_inner(self) -> IoUringBufRing<Vec<u8>> {
38        self.buf_ring
39    }
40
41    /// ## Safety
42    /// * `available_len` should be the returned value from the op.
43    pub(crate) unsafe fn get_buffer(
44        &self,
45        buffer_id: u16,
46        available_len: usize,
47    ) -> io::Result<BorrowedBuffer<'_>> {
48        unsafe { self.buf_ring.get_buf(buffer_id, available_len) }
49            .map(BorrowedBuffer)
50            .ok_or_else(|| io::Error::other(format!("cannot find buffer {buffer_id}")))
51    }
52
53    pub(crate) fn reuse_buffer(&self, buffer_id: u16) {
54        // SAFETY: 0 is always valid length. We just want to get the buffer once and
55        // return it immediately.
56        unsafe { self.buf_ring.get_buf(buffer_id, 0) };
57    }
58}
59
60/// Buffer borrowed from buffer pool
61///
62/// When IO operation finish, user will obtain a `BorrowedBuffer` to access the
63/// filled data
64pub struct BorrowedBuffer<'a>(io_uring_buf_ring::BorrowedBuffer<'a, Vec<u8>>);
65
66impl Debug for BorrowedBuffer<'_> {
67    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
68        f.debug_struct("BorrowedBuffer").finish_non_exhaustive()
69    }
70}
71
72impl Deref for BorrowedBuffer<'_> {
73    type Target = [u8];
74
75    fn deref(&self) -> &Self::Target {
76        self.0.deref()
77    }
78}
79
80impl DerefMut for BorrowedBuffer<'_> {
81    fn deref_mut(&mut self) -> &mut Self::Target {
82        self.0.deref_mut()
83    }
84}
85
86impl AsRef<[u8]> for BorrowedBuffer<'_> {
87    fn as_ref(&self) -> &[u8] {
88        self.deref()
89    }
90}
91
92impl AsMut<[u8]> for BorrowedBuffer<'_> {
93    fn as_mut(&mut self) -> &mut [u8] {
94        self.deref_mut()
95    }
96}
97
98impl Borrow<[u8]> for BorrowedBuffer<'_> {
99    fn borrow(&self) -> &[u8] {
100        self.deref()
101    }
102}
103
104impl BorrowMut<[u8]> for BorrowedBuffer<'_> {
105    fn borrow_mut(&mut self) -> &mut [u8] {
106        self.deref_mut()
107    }
108}