use crate::{ring::XskRingCons, socket::Socket};
use super::frame::FrameDesc;
#[derive(Debug)]
pub struct CompQueue {
ring: XskRingCons,
_socket: Socket,
}
impl CompQueue {
pub(crate) fn new(ring: XskRingCons, socket: Socket) -> Self {
Self {
ring,
_socket: socket,
}
}
#[inline]
pub unsafe fn consume(&mut self, descs: &mut [FrameDesc]) -> usize {
let nb = descs.len() as u32;
if nb == 0 {
return 0;
}
let mut idx = 0;
let cnt = unsafe { libxdp_sys::xsk_ring_cons__peek(self.ring.as_ptr(), nb, &mut idx) };
if cnt > 0 {
for desc in descs.iter_mut().take(cnt as usize) {
let addr =
unsafe { *libxdp_sys::xsk_ring_cons__comp_addr(self.ring.as_ptr(), idx) };
desc.addr = addr as usize;
desc.lengths.data = 0;
desc.lengths.headroom = 0;
desc.options = 0;
idx = idx.wrapping_add(1);
}
unsafe { libxdp_sys::xsk_ring_cons__release(self.ring.as_ptr(), cnt) };
}
cnt as usize
}
#[inline]
pub unsafe fn consume_one(&mut self, desc: &mut FrameDesc) -> usize {
let mut idx = 0;
let cnt = unsafe { libxdp_sys::xsk_ring_cons__peek(self.ring.as_ptr(), 1, &mut idx) };
if cnt > 0 {
let addr = unsafe { *libxdp_sys::xsk_ring_cons__comp_addr(self.ring.as_ptr(), idx) };
desc.addr = addr as usize;
desc.lengths.data = 0;
desc.lengths.headroom = 0;
desc.options = 0;
unsafe { libxdp_sys::xsk_ring_cons__release(self.ring.as_ptr(), cnt) };
}
cnt as usize
}
}