77//! by [`FixedBufPool`].
88//!
99//! [`FixedBufPool`]: self::FixedBufPool
10-
1110use super :: plumbing;
1211use super :: FixedBuf ;
1312use crate :: buf:: IoBufMut ;
14- use crate :: runtime :: CONTEXT ;
13+ use std :: cell :: RefCell ;
1514
15+ use crate :: buf:: fixed:: handle:: CheckedOutBuf ;
16+ use crate :: buf:: fixed:: plumbing:: Pool ;
17+ use crate :: buf:: fixed:: shared:: { process, register, unregister} ;
1618use std:: io;
1719use std:: rc:: Rc ;
1820use std:: sync:: Arc ;
@@ -93,7 +95,7 @@ use tokio::sync::Notify;
9395/// ```
9496#[ derive( Clone ) ]
9597pub struct FixedBufPool < T : IoBufMut > {
96- inner : Rc < plumbing:: Pool < T > > ,
98+ inner : RefCell < Rc < RefCell < plumbing:: Pool < T > > > > ,
9799}
98100
99101impl < T : IoBufMut > FixedBufPool < T > {
@@ -162,7 +164,7 @@ impl<T: IoBufMut> FixedBufPool<T> {
162164 /// ```
163165 pub fn new ( bufs : impl IntoIterator < Item = T > ) -> Self {
164166 FixedBufPool {
165- inner : Rc :: new ( plumbing :: Pool :: new ( bufs. into_iter ( ) ) ) ,
167+ inner : RefCell :: new ( Rc :: new ( RefCell :: new ( Pool :: new ( bufs. into_iter ( ) ) ) ) ) ,
166168 }
167169 }
168170
@@ -186,7 +188,7 @@ impl<T: IoBufMut> FixedBufPool<T> {
186188 /// of the `tokio-uring` runtime this call is made in, the function returns
187189 /// an error.
188190 pub fn register ( & self ) -> io:: Result < ( ) > {
189- CONTEXT . with ( |x| x . handle ( ) . register_buffers ( Rc :: clone ( & self . inner ) as _ ) )
191+ register ( self . inner . borrow ( ) . clone ( ) )
190192 }
191193
192194 /// Unregisters this collection of buffers.
@@ -204,8 +206,9 @@ impl<T: IoBufMut> FixedBufPool<T> {
204206 /// of the `tokio-uring` runtime this call is made in, the function returns
205207 /// an error. Calling `unregister` when no `FixedBufPool` is currently
206208 /// registered on this runtime also returns an error.
209+ #[ allow( private_interfaces) ]
207210 pub fn unregister ( & self ) -> io:: Result < ( ) > {
208- CONTEXT . with ( |x| x . handle ( ) . unregister_buffers ( Rc :: clone ( & self . inner ) as _ ) )
211+ unregister ( )
209212 }
210213
211214 /// Returns a buffer of requested capacity from this pool
@@ -220,14 +223,13 @@ impl<T: IoBufMut> FixedBufPool<T> {
220223 /// An application should not rely on any particular order
221224 /// in which available buffers are retrieved.
222225 pub fn try_next ( & mut self , cap : usize ) -> Option < FixedBuf > {
223- let mut inner = Rc :: get_mut ( & mut self . inner ) ;
224-
225- inner. as_mut ( ) ?. try_next ( cap) . map ( |data| {
226- let pool = Rc :: clone ( & self . inner ) ;
227- // Safety: the validity of buffer data is ensured by
228- // plumbing::Pool::try_next
229- unsafe { FixedBuf :: new ( pool, data) }
230- } )
226+ let cob = {
227+ let inner = self . inner . borrow_mut ( ) ;
228+ let mut inner = inner. borrow_mut ( ) ;
229+ inner. try_next ( cap)
230+ } ;
231+ let current = self . inner . borrow ( ) . clone ( ) ;
232+ process ( current, cob)
231233 }
232234
233235 /// Resolves to a buffer of requested capacity
@@ -243,12 +245,11 @@ impl<T: IoBufMut> FixedBufPool<T> {
243245 pub async fn next ( & mut self , cap : usize ) -> FixedBuf {
244246 // Fast path: get the buffer if it's already available
245247 let notify = {
246- let inner = Rc :: get_mut ( & mut self . inner ) . unwrap ( ) ;
248+ let item = self . inner . borrow ( ) ;
249+ let mut inner = item. borrow_mut ( ) ;
247250 if let Some ( data) = inner. try_next ( cap) {
248- // Safety: the validity of buffer data is ensured by
249- // plumbing::Pool::try_next
250- let buf = unsafe { FixedBuf :: new ( Rc :: clone ( & self . inner ) as _ , data) } ;
251- return buf;
251+ let current = self . inner . borrow ( ) . clone ( ) ;
252+ return Self :: get_fixed_buf ( current, data) ;
252253 }
253254 inner. notify_on_next ( cap)
254255 } ;
@@ -257,6 +258,12 @@ impl<T: IoBufMut> FixedBufPool<T> {
257258 self . next_when_notified ( cap, notify) . await
258259 }
259260
261+ fn get_fixed_buf ( inner : Rc < RefCell < Pool < T > > > , data : CheckedOutBuf ) -> FixedBuf {
262+ // Safety: the validity of buffer data is ensured by
263+ // plumbing::Pool::try_next
264+ unsafe { FixedBuf :: new ( inner, data) }
265+ }
266+
260267 #[ cold]
261268 async fn next_when_notified ( & mut self , cap : usize , notify : Arc < Notify > ) -> FixedBuf {
262269 let notified = notify. notified ( ) ;
@@ -266,11 +273,12 @@ impl<T: IoBufMut> FixedBufPool<T> {
266273 // between us calling `try_next` and here, so we can't miss a wakeup.
267274 notified. as_mut ( ) . await ;
268275
269- if let Some ( data) = Rc :: get_mut ( & mut self . inner ) . unwrap ( ) . try_next ( cap) {
270- // Safety: the validity of buffer data is ensured by
271- // plumbing::Pool::try_next
272- let buf = unsafe { FixedBuf :: new ( Rc :: clone ( & self . inner ) as _ , data) } ;
273- return buf;
276+ let inner = self . inner . borrow_mut ( ) ;
277+ let mut inner = inner. borrow_mut ( ) ;
278+
279+ if let Some ( data) = inner. try_next ( cap) {
280+ let current = self . inner . borrow ( ) . clone ( ) ;
281+ return Self :: get_fixed_buf ( current, data) ;
274282 }
275283
276284 // It's possible that the task did not get a buffer from `try_next`.
0 commit comments