core: Switch to using Arc<Completion>

We need to be able to leak a reference for io_uring so switch to
Arc<Completion> in the code.
This commit is contained in:
Pekka Enberg
2024-01-13 09:03:21 +02:00
parent ae2f403838
commit 5ea214083a
5 changed files with 38 additions and 16 deletions

View File

@@ -27,10 +27,12 @@ pub struct File {
}
impl File {
pub fn pread(&self, pos: usize, c: &mut Completion) -> Result<()> {
pub fn pread(&self, pos: usize, c: Arc<Completion>) -> Result<()> {
let mut file = self.file.borrow_mut();
file.seek(std::io::SeekFrom::Start(pos as u64))?;
file.read_exact(c.buf.as_mut_slice())?;
let buf = c.buf();
let mut buf = buf.as_mut_slice();
file.read_exact(buf)?;
Ok(())
}
}

View File

@@ -3,6 +3,7 @@ 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<RefCell<io_uring::IoUring>>,
@@ -38,9 +39,12 @@ pub struct File {
}
impl File {
pub fn pread(&self, pos: usize, c: &mut Completion) -> Result<()> {
pub fn pread(&self, pos: usize, c: Arc<Completion>) -> Result<()> {
let fd = io_uring::types::Fd(self.file.as_raw_fd());
let read_e = io_uring::opcode::Read::new(fd, c.buf.as_mut_ptr(), c.buf.len() as u32 )
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();

View File

@@ -1,20 +1,35 @@
use cfg_block::cfg_block;
use std::{mem::ManuallyDrop, pin::Pin, sync::Arc};
use std::{
cell::{Ref, RefCell, RefMut},
mem::ManuallyDrop,
pin::Pin,
sync::Arc,
};
pub type Complete = dyn Fn(&Buffer) + Send + Sync;
pub struct Completion {
pub buf: Buffer,
pub buf: RefCell<Buffer>,
pub complete: Box<Complete>,
}
impl Completion {
pub fn new(buf: Buffer, complete: Box<Complete>) -> Self {
let buf = RefCell::new(buf);
Self { buf, complete }
}
pub fn buf<'a>(&'a self) -> Ref<'a, Buffer> {
self.buf.borrow()
}
pub fn buf_mut<'a>(&'a self) -> RefMut<'a, Buffer> {
self.buf.borrow_mut()
}
pub fn complete(&self) {
(self.complete)(&self.buf);
let buf = self.buf.borrow_mut();
(self.complete)(&buf);
}
}

View File

@@ -65,9 +65,10 @@ pub fn read_database_header(storage: &Storage) -> Result<DatabaseHeader> {
let drop_fn = Arc::new(|_buf| {});
let buf = Buffer::allocate(512, drop_fn);
let complete = Box::new(move |_buf: &Buffer| {});
let mut c = Completion::new(buf, complete);
storage.get(1, &mut c)?;
let buf = c.buf.as_slice();
let c = Arc::new(Completion::new(buf, complete));
storage.get(1, c.clone())?;
let buf = c.buf();
let buf = buf.as_slice();
let mut header = DatabaseHeader::default();
header.magic.copy_from_slice(&buf[0..16]);
header.page_size = u16::from_be_bytes([buf[16], buf[17]]);
@@ -152,8 +153,8 @@ pub fn begin_read_btree_page(
page.set_error();
}
});
let mut c = Completion::new(buf, complete);
storage.get(page_idx, &mut c)?;
let c = Arc::new(Completion::new(buf, complete));
storage.get(page_idx, c.clone())?;
c.complete();
Ok(())
}

View File

@@ -18,13 +18,13 @@ impl Storage {
}
}
pub fn get(&self, page_idx: usize, c: &mut Completion) -> Result<()> {
pub fn get(&self, page_idx: usize, c: Arc<Completion>) -> Result<()> {
self.io.get(page_idx, c)
}
}
pub trait StorageIO {
fn get(&self, page_idx: usize, c: &mut Completion) -> Result<()>;
fn get(&self, page_idx: usize, c: Arc<Completion>) -> Result<()>;
}
#[cfg(feature = "fs")]
@@ -34,8 +34,8 @@ struct FileStorage {
#[cfg(feature = "fs")]
impl StorageIO for FileStorage {
fn get(&self, page_idx: usize, c: &mut Completion) -> Result<()> {
let page_size = c.buf.len();
fn get(&self, page_idx: usize, c: Arc<Completion>) -> Result<()> {
let page_size = c.buf().len();
assert!(page_idx > 0);
assert!(page_size >= 512);
assert!(page_size <= 65536);