got meaningful error:

error[E0521]: borrowed data escapes outside of method
     --> repro-problem/src/virtual_file.rs:702:51
      |
  692 | impl<'a> FileGuard<'a> {
      |      -- lifetime `'a` defined here
  ...
  695 |     fn with_std_file<F, R>(&mut self, with: F) -> R
      |                            --------- `self` is a reference that is only valid in the method body
  ...
  702 |         let mut file = unsafe { File::from_raw_fd(self.as_ref().as_raw_fd()) };
      |                                                   ^^^^^^^^^^^^^
      |                                                   |
      |                                                   `self` escapes the method body here
      |                                                   argument requires that `'a` must outlive `'static`
      |
      = note: requirement occurs because of a mutable reference to `FileGuard<'_>`
      = note: mutable references are invariant over their type parameter
      = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
This commit is contained in:
Christian Schwarz
2023-12-11 17:18:40 +00:00
parent b5eb1bb1ae
commit c4ddc6abaf
2 changed files with 41 additions and 42 deletions

View File

@@ -4,8 +4,8 @@ mod virtual_file;
#[tokio::main]
async fn main() {
let file = VirtualFile::open(camino::Utf8Path::new("foo")).await.unwrap();
file.read_exact_at().await;
let file = VirtualFile::open(camino::Utf8Path::new("foo"))
.await
.unwrap();
file.read_exact_at(vec![0; 8], 0).await;
}

View File

@@ -10,7 +10,7 @@
//! This is similar to PostgreSQL's virtual file descriptor facility in
//! src/backend/storage/file/fd.c
//!
use crate::page_cache::PageWriteGuard;
// use crate::page_cache::PageWriteGuard;
use camino::{Utf8Path, Utf8PathBuf};
use once_cell::sync::OnceCell;
use std::fs::{self, File};
@@ -574,48 +574,47 @@ impl VirtualFile {
// }
pub async fn read_exact_at(
&self,
write_guard: PageWriteGuard<'static>,
buf: Vec<u8>,
offset: u64,
) -> Result<PageWriteGuard<'static>, Error> {
let write_guard: PageWriteGuard<'static> = write_guard;
) -> Result<Vec<u8>, Error> {
let file_guard: FileGuard<'static> = self.lock_file().await?;
let system = tokio_epoll_uring::thread_local_system().await;
struct PageWriteGuardBuf {
buf: PageWriteGuard<'static>,
init_up_to: usize,
}
unsafe impl tokio_epoll_uring::IoBuf for PageWriteGuardBuf {
fn stable_ptr(&self) -> *const u8 {
self.buf.as_ptr()
}
fn bytes_init(&self) -> usize {
self.init_up_to
}
fn bytes_total(&self) -> usize {
self.buf.len()
}
}
unsafe impl tokio_epoll_uring::IoBufMut for PageWriteGuardBuf {
fn stable_mut_ptr(&mut self) -> *mut u8 {
self.buf.as_mut_ptr()
}
// struct PageWriteGuardBuf {
// buf: PageWriteGuard<'static>,
// init_up_to: usize,
// }
// unsafe impl tokio_epoll_uring::IoBuf for PageWriteGuardBuf {
// fn stable_ptr(&self) -> *const u8 {
// self.buf.as_ptr()
// }
// fn bytes_init(&self) -> usize {
// self.init_up_to
// }
// fn bytes_total(&self) -> usize {
// self.buf.len()
// }
// }
// unsafe impl tokio_epoll_uring::IoBufMut for PageWriteGuardBuf {
// fn stable_mut_ptr(&mut self) -> *mut u8 {
// self.buf.as_mut_ptr()
// }
unsafe fn set_init(&mut self, pos: usize) {
assert!(pos <= self.buf.len());
self.init_up_to = pos;
}
}
let buf = PageWriteGuardBuf {
buf: write_guard,
init_up_to: 0,
};
let ((_, buf), res) = system.read(file_guard, offset, buf).await;
let PageWriteGuardBuf {
buf: write_guard,
init_up_to,
} = buf;
// unsafe fn set_init(&mut self, pos: usize) {
// assert!(pos <= self.buf.len());
// self.init_up_to = pos;
// }
// }
// let buf = PageWriteGuardBuf {
// buf: write_guard,
// init_up_to: 0,
// };
let ((_, write_guard), res) = system.read(file_guard, offset, buf).await;
// let PageWriteGuardBuf {
// buf: write_guard,
// init_up_to,
// } = buf;
if let Ok(num_read) = res {
assert!(init_up_to == num_read); // TODO need to deal with short reads here
// assert!(init_up_to == num_read); // TODO need to deal with short reads here
}
res.map(|_| write_guard)
.map_err(|e| Error::new(ErrorKind::Other, e))