@@ -7,16 +7,32 @@ use std::{
77 fmt:: { Debug , Formatter } ,
88 io,
99 ops:: { Deref , DerefMut } ,
10+ rc:: Rc ,
1011} ;
1112
1213use io_uring_buf_ring:: IoUringBufRing ;
14+ #[ cfg( not( fusion) ) ]
15+ pub use { BufferPool as IoUringBufferPool , OwnedBuffer as IoUringOwnedBuffer } ;
16+
17+ struct BufferPoolInner {
18+ buf_ring : IoUringBufRing < Vec < u8 > > ,
19+ }
20+
21+ impl BufferPoolInner {
22+ fn reuse_buffer ( & self , buffer_id : u16 ) {
23+ // SAFETY: 0 is always valid length. We just want to get the buffer once and
24+ // return it immediately.
25+ unsafe { self . buf_ring . get_buf ( buffer_id, 0 ) } ;
26+ }
27+ }
1328
1429/// Buffer pool
1530///
1631/// A buffer pool to allow user no need to specify a specific buffer to do the
1732/// IO operation
33+ #[ derive( Clone ) ]
1834pub struct BufferPool {
19- buf_ring : IoUringBufRing < Vec < u8 > > ,
35+ inner : Rc < BufferPoolInner > ,
2036}
2137
2238impl Debug for BufferPool {
@@ -27,33 +43,67 @@ impl Debug for BufferPool {
2743
2844impl BufferPool {
2945 pub ( crate ) fn new ( buf_ring : IoUringBufRing < Vec < u8 > > ) -> Self {
30- Self { buf_ring }
46+ Self {
47+ inner : Rc :: new ( BufferPoolInner { buf_ring } ) ,
48+ }
3149 }
3250
3351 pub ( crate ) fn buffer_group ( & self ) -> u16 {
34- self . buf_ring . buffer_group ( )
52+ self . inner . buf_ring . buffer_group ( )
53+ }
54+
55+ pub ( crate ) fn into_inner ( self ) -> Result < IoUringBufRing < Vec < u8 > > , Self > {
56+ Rc :: try_unwrap ( self . inner )
57+ . map ( |inner| inner. buf_ring )
58+ . map_err ( |inner| Self { inner } )
3559 }
3660
37- pub ( crate ) fn into_inner ( self ) -> IoUringBufRing < Vec < u8 > > {
38- self . buf_ring
61+ #[ doc( hidden) ]
62+ pub unsafe fn get_buffer ( & self , buffer_id : u16 , available_len : usize ) -> OwnedBuffer {
63+ OwnedBuffer {
64+ pool : self . inner . clone ( ) ,
65+ params : Some ( ( buffer_id, available_len) ) ,
66+ }
3967 }
4068
4169 /// ## Safety
42- /// * `available_len ` should be the returned value from the op.
43- pub ( crate ) unsafe fn get_buffer (
70+ /// * `len ` should be the returned value from the op.
71+ pub ( crate ) unsafe fn create_proxy (
4472 & self ,
45- buffer_id : u16 ,
46- available_len : usize ,
73+ slice : OwnedBuffer ,
74+ len : usize ,
4775 ) -> io:: Result < BorrowedBuffer < ' _ > > {
48- unsafe { self . buf_ring . get_buf ( buffer_id, available_len) }
76+ let Some ( ( buffer_id, available_len) ) = slice. leak ( ) else {
77+ return Err ( io:: Error :: other ( "no buffer selected" ) ) ;
78+ } ;
79+ debug_assert_eq ! ( available_len, len) ;
80+ unsafe { self . inner . buf_ring . get_buf ( buffer_id, available_len) }
4981 . map ( BorrowedBuffer )
5082 . ok_or_else ( || io:: Error :: other ( format ! ( "cannot find buffer {buffer_id}" ) ) )
5183 }
5284
5385 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 ) } ;
86+ self . inner . reuse_buffer ( buffer_id) ;
87+ }
88+ }
89+
90+ #[ doc( hidden) ]
91+ pub struct OwnedBuffer {
92+ pool : Rc < BufferPoolInner > ,
93+ params : Option < ( u16 , usize ) > ,
94+ }
95+
96+ impl OwnedBuffer {
97+ pub fn leak ( mut self ) -> Option < ( u16 , usize ) > {
98+ self . params . take ( )
99+ }
100+ }
101+
102+ impl Drop for OwnedBuffer {
103+ fn drop ( & mut self ) {
104+ if let Some ( ( buffer_id, _) ) = self . params {
105+ self . pool . reuse_buffer ( buffer_id) ;
106+ }
57107 }
58108}
59109
0 commit comments