#![cfg(feature = "io-uring")]
use crate::ZmqError;
use bytes::BytesMut;
use io_uring::IoUring;
use io_uring_buf_ring::{BorrowedBuffer, IoUringBufRing};
use std::fmt;
pub struct BufferRingManager {
buf_ring_instance: IoUringBufRing<BytesMut>,
}
impl fmt::Debug for BufferRingManager {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BufferRingManager")
.field("bgid", &self.buf_ring_instance.buffer_group())
.finish_non_exhaustive()
}
}
impl BufferRingManager {
pub fn new(
ring: &IoUring,
ring_entries: u16,
bgid: u16,
buffer_capacity: usize,
) -> Result<Self, ZmqError> {
tracing::info!(
"Initializing BufferRingManager with bgid: {}, requested_entries: {}, capacity_per_buffer: {}",
bgid,
ring_entries,
buffer_capacity
);
let bufs_iter = (0..ring_entries).map(|_| BytesMut::with_capacity(buffer_capacity));
match IoUringBufRing::new_with_buffers(ring, bufs_iter, bgid) {
Ok(buf_ring_instance) => {
tracing::info!(
"BufferRingManager: IoUringBufRing built and registered successfully for bgid: {}",
bgid
);
Ok(Self { buf_ring_instance })
}
Err(e) => {
tracing::error!("Failed to build and register IoUringBufRing: {:?}", e);
Err(ZmqError::Internal(format!(
"BufferRingManager build failed: {:?}",
e
)))
}
}
}
pub fn group_id(&self) -> u16 {
self.buf_ring_instance.buffer_group()
}
pub unsafe fn borrow_kernel_filled_buffer(
&self,
buffer_id: u16,
available_len: usize,
) -> Result<BorrowedBuffer<BytesMut>, ZmqError> {
self
.buf_ring_instance
.get_buf(buffer_id, available_len)
.ok_or_else(|| {
ZmqError::Internal(format!(
"Failed to borrow buffer ID {} from ring",
buffer_id
))
})
}
}