use std::io;
#[cfg(target_os = "linux")]
use {
crate::io_uring::sqpoll::SharedSqPoll,
std::os::fd::{AsFd as _, BorrowedFd},
};
#[derive(Default)]
pub struct IoSetupState {
#[cfg(target_os = "linux")]
shared_sqpoll: Option<SharedSqPoll>,
pub use_direct_io: bool,
pub use_registered_io_uring_buffers: bool,
}
impl IoSetupState {
pub fn with_shared_sqpoll(self) -> io::Result<Self> {
Ok(Self {
#[cfg(target_os = "linux")]
shared_sqpoll: Some(SharedSqPoll::new()?),
..self
})
}
pub fn with_buffers_registered(mut self, fixed: bool) -> Self {
self.use_registered_io_uring_buffers = fixed;
self
}
pub fn with_direct_io(mut self, use_direct_io: bool) -> Self {
self.use_direct_io = use_direct_io;
self
}
#[cfg(target_os = "linux")]
pub(crate) fn shared_sqpoll_fd(&self) -> Option<BorrowedFd<'_>> {
self.shared_sqpoll.as_ref().map(|s| s.as_fd())
}
}
#[cfg(all(test, target_os = "linux"))]
mod tests {
use {
super::*,
crate::{
file_io::FileCreator,
io_uring::{
file_creator::IoUringFileCreatorBuilder,
sequential_file_reader::SequentialFileReaderBuilder,
},
},
rand::RngCore,
std::{
fs::File,
io::{Cursor, Read},
sync::{Arc, RwLock},
},
};
#[test]
fn test_shared_sqpoll_read_and_create() {
let io_setup = &IoSetupState::default().with_shared_sqpoll().unwrap();
let read_bytes = RwLock::new(vec![]);
let read_bytes_ref = &read_bytes;
let mut file_creator = IoUringFileCreatorBuilder::new()
.shared_sqpoll(io_setup.shared_sqpoll_fd())
.build(1 << 20, move |file_info| {
let mut reader = SequentialFileReaderBuilder::new()
.shared_sqpoll(io_setup.shared_sqpoll_fd())
.build(1 << 20)
.unwrap();
reader.set_path(file_info.path).unwrap();
reader
.read_to_end(read_bytes_ref.write().unwrap().as_mut())
.unwrap();
None
})
.unwrap();
let temp_dir = tempfile::tempdir().unwrap();
let dir_handle = Arc::new(File::open(temp_dir.path()).unwrap());
let mut write_bytes = vec![0; 2 << 20];
rand::rng().fill_bytes(&mut write_bytes);
let file_path1 = temp_dir.path().join("test-1.txt");
let file_path2 = temp_dir.path().join("test-2.txt");
for path in [file_path1, file_path2] {
let dir_handle = dir_handle.clone();
file_creator
.schedule_create_at_dir(path, 0o644, dir_handle, &mut Cursor::new(&write_bytes))
.unwrap();
}
file_creator.drain().unwrap();
drop(file_creator);
let read_bytes = read_bytes.into_inner().unwrap();
assert_eq!(&read_bytes[..write_bytes.len()], &write_bytes);
assert_eq!(&read_bytes[write_bytes.len()..], &write_bytes);
}
}