use io_uring::{squeue, IoUring};
use wireshift_core::{Error, Result};
pub(crate) fn push_entry(ring: &mut IoUring, entry: &squeue::Entry) -> Result<()> {
let mut submission = ring.submission();
unsafe {
submission.push(entry).map_err(|_| {
Error::submission(
"io_uring submission queue is full",
"drain completions or increase queue_depth in RingConfig",
)
})?;
}
submission.sync();
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use io_uring::{opcode, types};
#[test]
fn test_push_entry_queue_full() {
let mut ring = IoUring::new(2).unwrap();
let mut buf = [0u8; 1];
let entry = opcode::Read::new(types::Fd(0), buf.as_mut_ptr(), 1).build();
push_entry(&mut ring, &entry).unwrap();
push_entry(&mut ring, &entry).unwrap();
let result = push_entry(&mut ring, &entry);
assert!(result.is_err());
assert_eq!(result.unwrap_err().to_string(), "io_uring submission queue is full. Fix: drain completions or increase queue_depth in RingConfig");
}
#[test]
fn test_push_entry_invariant_drop() {
let mut ring = IoUring::new(2).unwrap();
let entry = opcode::Nop::new().build().user_data(42);
push_entry(&mut ring, &entry).unwrap();
ring.submit_and_wait(1).unwrap();
let cqes: Vec<_> = ring.completion().collect();
assert_eq!(cqes.len(), 1);
assert_eq!(cqes[0].user_data(), 42);
}
}