pub struct FixedBufPool<T: IoBufMut> { /* private fields */ }Expand description
A dynamic collection of I/O buffers pre-registered with the kernel.
FixedBufPool allows the application to manage a collection of buffers
allocated in memory, that can be registered in the current tokio-uring
context using the register method. Unlike FixedBufRegistry,
individual buffers are not retrieved by index; instead, an available
buffer matching a specified capacity can be retrieved with the try_next
method. In asynchronous contexts, the next method can be used to wait
until such a buffer becomes available.
This allows some flexibility in managing sets of buffers with
different capacity tiers. The need to maintain lists of free buffers,
however, imposes additional runtime overhead.
A FixedBufPool value is a lightweight handle for a collection of
allocated buffers. Cloning of a FixedBufPool creates a new reference to
the same collection of buffers.
The buffers of the collection are not deallocated until:
- all
FixedBufPoolreferences to the collection have been dropped; - all
FixedBufhandles to individual buffers in the collection have been dropped, including the buffer handles owned by any I/O operations in flight; - The
tokio-uringRuntimethe buffers are registered with has been dropped.
§Examples
use tokio_uring::buf::fixed::FixedBufPool;
use tokio_uring::buf::IoBuf;
use std::iter;
use std::mem;
tokio_uring::start(async {
let pool = FixedBufPool::new(
iter::once(Vec::with_capacity(BUF_SIZE_LARGE))
.chain(iter::repeat_with(|| Vec::with_capacity(BUF_SIZE_SMALL)).take(2))
);
pool.register()?;
let buf = pool.try_next(BUF_SIZE_LARGE).unwrap();
assert_eq!(buf.bytes_total(), BUF_SIZE_LARGE);
let next = pool.try_next(BUF_SIZE_LARGE);
assert!(next.is_none());
let buf1 = pool.try_next(BUF_SIZE_SMALL).unwrap();
assert_eq!(buf1.bytes_total(), BUF_SIZE_SMALL);
let buf2 = pool.try_next(BUF_SIZE_SMALL).unwrap();
assert_eq!(buf2.bytes_total(), BUF_SIZE_SMALL);
let next = pool.try_next(BUF_SIZE_SMALL);
assert!(next.is_none());
mem::drop(buf);
let buf = pool.try_next(BUF_SIZE_LARGE).unwrap();
assert_eq!(buf.bytes_total(), BUF_SIZE_LARGE);
Ok(())
})Implementations§
Source§impl<T: IoBufMut> FixedBufPool<T>
impl<T: IoBufMut> FixedBufPool<T>
Sourcepub fn new(bufs: impl IntoIterator<Item = T>) -> Self
pub fn new(bufs: impl IntoIterator<Item = T>) -> Self
Creates a new collection of buffers from the provided allocated vectors.
The buffers are assigned 0-based indices in the order of the iterable
input parameter. The returned collection takes up to UIO_MAXIOV
buffers from the input. Any items in excess of that amount are silently
dropped, unless the input iterator produces the vectors lazily.
§Examples
When providing uninitialized vectors for the collection, take care to
not replicate a vector with .clone() as that does not preserve the
capacity and the resulting buffer pointer will be rejected by the kernel.
This means that the following use of iter::repeat would not work:
use tokio_uring::buf::fixed::FixedBufPool;
use std::iter;
let pool = FixedBufPool::new(
iter::repeat(Vec::with_capacity(BUF_SIZE)).take(NUM_BUFFERS)
);
tokio_uring::start(async {
pool.register()?;
// ...
Ok(())
})Instead, create the vectors with requested capacity directly:
use tokio_uring::buf::fixed::FixedBufPool;
use std::iter;
let pool = FixedBufPool::new(
iter::repeat_with(|| Vec::with_capacity(BUF_SIZE)).take(NUM_BUFFERS)
);
tokio_uring::start(async {
pool.register()?;
// ...
Ok(())
})Sourcepub fn register(&self) -> Result<()>
pub fn register(&self) -> Result<()>
Registers the buffers with the kernel.
This method must be called in the context of a tokio-uring runtime.
The registration persists for the lifetime of the runtime, unless
revoked by the unregister method. Dropping the
FixedBufPool instance this method has been called on does not revoke
the registration or deallocate the buffers.
This call can be blocked in the kernel to complete any operations
in-flight on the same io-uring instance. The application is
recommended to register buffers before starting any I/O operations.
§Errors
If a collection of buffers is currently registered in the context
of the tokio-uring runtime this call is made in, the function returns
an error.
Sourcepub fn unregister(&self) -> Result<()>
pub fn unregister(&self) -> Result<()>
Unregisters this collection of buffers.
This method must be called in the context of a tokio-uring runtime,
where the buffers should have been previously registered.
This operation invalidates any FixedBuf handles checked out from
this registry instance. Continued use of such handles in I/O
operations may result in an error.
§Errors
If another collection of buffers is currently registered in the context
of the tokio-uring runtime this call is made in, the function returns
an error. Calling unregister when no FixedBufPool is currently
registered on this runtime also returns an error.
Sourcepub fn try_next(&self, cap: usize) -> Option<FixedBuf>
pub fn try_next(&self, cap: usize) -> Option<FixedBuf>
Returns a buffer of requested capacity from this pool
that is not currently owned by any other FixedBuf handle.
If no such free buffer is available, returns None.
The buffer is released to be available again once the
returned FixedBuf handle has been dropped. An I/O operation
using the buffer takes ownership of it and returns it once completed,
preventing shared use of the buffer while the operation is in flight.
An application should not rely on any particular order in which available buffers are retrieved.
Sourcepub async fn next(&self, cap: usize) -> FixedBuf
pub async fn next(&self, cap: usize) -> FixedBuf
Resolves to a buffer of requested capacity
when it is or becomes available in this pool.
This may happen when a FixedBuf handle owning a buffer
of the same capacity is dropped.
If no matching buffers are available and none are being released,
this asynchronous function will never resolve. Applications should take
care to wait on the returned future concurrently with some tasks that
will complete I/O operations owning the buffers, or back it up with a
timeout using, for example, tokio::util::timeout.
Trait Implementations§
Source§impl<T: Clone + IoBufMut> Clone for FixedBufPool<T>
impl<T: Clone + IoBufMut> Clone for FixedBufPool<T>
Source§fn clone(&self) -> FixedBufPool<T>
fn clone(&self) -> FixedBufPool<T>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more