To perform asynchronous I/O operations, you must initialize an IoUring instance, build an opcode (such as Read), push it to the submission queue, and then wait for the completion queue entry (CQE).
Important Safety Note: The developer is responsible for ensuring that the entries pushed into the submission queue remain valid (e.g., the file descriptor and the buffer must not be dropped or moved) until the operation completes.
Kernel Requirement: The Read opcode requires Linux kernel 5.6 or higher. Using a kernel version lower than 5.6 will cause the operation to fail.
use io_uring::{opcode, types, IoUring};
use std::os::unix::io::AsRawFd;
use std::{fs, io};
fn main() -> io::Result<()> {
let mut ring = IoUring::new(8)?;
let fd = fs::File::open("README.md")?;
let mut buf = vec![0; 1024];
let read_e = opcode::Read::new(types::Fd(fd.as_raw_fd()), buf.as_mut_ptr(), buf.len() as _)
.build()
.user_data(0x42);
// Note that the developer needs to ensure
// that the entry pushed into submission queue is valid (e.g. fd, buffer).
unsafe {
ring.submission()
.push(&read_e)
.expect("submission queue is full");
}
ring.submit_and_wait(1)?;
let cqe = ring.completion().next().expect("completion queue is empty");
assert_eq!(cqe.user_data(), 0x42);
assert!(cqe.result() >= 0, "read error: {}", cqe.result());
Ok()
}