use super::Completion; use anyhow::Result; use std::cell::RefCell; use std::os::unix::io::AsRawFd; use std::rc::Rc; use std::sync::Arc; pub struct IO { ring: Rc>, } impl IO { pub fn new() -> Result { let ring = io_uring::IoUring::new(8)?; Ok(Self { ring: Rc::new(RefCell::new(ring)), }) } pub fn open_file(&self, path: &str) -> Result { let file = std::fs::File::open(path)?; Ok(File { ring: self.ring.clone(), file, }) } pub fn run_once(&self) -> Result<()> { let mut ring = self.ring.borrow_mut(); ring.submit_and_wait(1)?; let cqe = ring.completion().next().expect("completion queue is empty"); Ok(()) } } pub struct File { ring: Rc>, file: std::fs::File, } impl File { pub fn pread(&self, pos: usize, c: Arc) -> Result<()> { let fd = io_uring::types::Fd(self.file.as_raw_fd()); let mut buf = c.buf_mut(); let len = buf.len(); let buf = buf.as_mut_ptr(); let read_e = io_uring::opcode::Read::new(fd, buf, len as u32 ) .offset(pos as u64) .build(); let mut ring = self.ring.borrow_mut(); 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"); Ok(()) } }