use std::{
io::{self, Read, Write},
os::unix::{io::AsRawFd, net},
};
const MESSAGE: &'static [u8] = b"Hello World";
#[test]
fn test_poll_add() -> io::Result<()> {
let mut ring = iou::IoUring::new(2)?;
let (mut read, mut write) = net::UnixStream::pair()?;
unsafe {
let mut sqe = ring.prepare_sqe().expect("failed to get sqe");
sqe.prep_poll_add(read.as_raw_fd(), iou::sqe::PollFlags::POLLIN);
sqe.set_user_data(0xDEADBEEF);
ring.submit_sqes()?;
}
write.write(MESSAGE)?;
let cqe = ring.wait_for_cqe()?;
assert_eq!(cqe.user_data(), 0xDEADBEEF);
let mask = unsafe { iou::sqe::PollFlags::from_bits_unchecked(cqe.result()? as _) };
assert!(mask.contains(iou::sqe::PollFlags::POLLIN));
let mut buf = [0; MESSAGE.len()];
read.read(&mut buf)?;
assert_eq!(buf, MESSAGE);
Ok(())
}
#[test]
fn test_poll_remove() -> io::Result<()> {
let mut ring = iou::IoUring::new(2)?;
let (read, _write) = net::UnixStream::pair()?;
let uname = nix::sys::utsname::uname();
let version = semver::Version::parse(uname.release());
unsafe {
let mut sqe = ring.prepare_sqe().expect("failed to get sqe");
sqe.prep_poll_add(read.as_raw_fd(), iou::sqe::PollFlags::POLLIN);
sqe.set_user_data(0xDEADBEEF);
ring.submit_sqes()?;
let mut sqe = ring.prepare_sqe().expect("failed to get sqe");
sqe.prep_poll_remove(0xDEADBEEF);
sqe.set_user_data(42);
ring.submit_sqes()?;
for _ in 0..2 {
let cqe = ring.wait_for_cqe()?;
let user_data = cqe.user_data();
if version < semver::Version::parse("5.5.0-0") {
let _ = cqe.result()?;
} else if user_data == 0xDEADBEEF {
let err = cqe
.result()
.expect_err("on kernels >=5.5 error is expected");
let err_no = nix::errno::Errno::from_i32(
err.raw_os_error()
.expect("on kernels >=5.5 os_error is expected"),
);
assert_eq!(err_no, nix::errno::Errno::ECANCELED);
} else {
let _ = cqe.result()?;
}
}
Ok(())
}
}