[wasi-common] Clean up the use of mutable Entry (#1395)
* Clean up the use of mutable Entry Until now, several syscalls including `fd_pwrite` etc. were relying on mutating `&mut Entry` by mutating its inner file handle. This is unnecessary in almost all cases since all methods mutating `std::fs::File` in Rust's libstd are also implemented for `&std::fs::File`. While here, I've also modified `OsHandle` in BSD to include `RefCell<Option<Dir>>` rather than `Option<Mutex<Dir>>` as was until now. While `RefCell` could easily be replaced with `RefCell`, since going multithreading will require a lot of (probably even) conceptual changes to `wasi-common`, I thought it'd be best not to mix single- with multithreading contexts and swap all places at once when it comes to it. I've also had to make some modifications to virtual FS which mainly swapped mutability for interior mutability in places. * Use one-liners wherever convenient
This commit is contained in:
@@ -1,26 +1,21 @@
|
||||
use crate::sys::entry::OsHandle;
|
||||
use crate::wasi::Result;
|
||||
use std::sync::{Mutex, MutexGuard};
|
||||
use std::cell::RefMut;
|
||||
use yanix::dir::Dir;
|
||||
|
||||
pub(crate) fn get_dir_from_os_handle<'a>(
|
||||
os_handle: &'a mut OsHandle,
|
||||
) -> Result<MutexGuard<'a, Dir>> {
|
||||
let dir = match os_handle.dir {
|
||||
Some(ref mut dir) => dir,
|
||||
None => {
|
||||
// We need to duplicate the fd, because `opendir(3)`:
|
||||
// Upon successful return from fdopendir(), the file descriptor is under
|
||||
// control of the system, and if any attempt is made to close the file
|
||||
// descriptor, or to modify the state of the associated description other
|
||||
// than by means of closedir(), readdir(), readdir_r(), or rewinddir(),
|
||||
// the behaviour is undefined.
|
||||
let fd = (*os_handle).try_clone()?;
|
||||
let dir = Dir::from(fd)?;
|
||||
os_handle.dir.get_or_insert(Mutex::new(dir))
|
||||
}
|
||||
};
|
||||
// Note that from this point on, until the end of the parent scope (i.e., enclosing this
|
||||
// function), we're locking the `Dir` member of this `OsHandle`.
|
||||
Ok(dir.lock().unwrap())
|
||||
pub(crate) fn get_dir_from_os_handle(os_handle: &OsHandle) -> Result<RefMut<Dir>> {
|
||||
if os_handle.dir.borrow().is_none() {
|
||||
// We need to duplicate the fd, because `opendir(3)`:
|
||||
// Upon successful return from fdopendir(), the file descriptor is under
|
||||
// control of the system, and if any attempt is made to close the file
|
||||
// descriptor, or to modify the state of the associated description other
|
||||
// than by means of closedir(), readdir(), readdir_r(), or rewinddir(),
|
||||
// the behaviour is undefined.
|
||||
let fd = (*os_handle).try_clone()?;
|
||||
let d = Dir::from(fd)?;
|
||||
*os_handle.dir.borrow_mut() = Some(d);
|
||||
}
|
||||
Ok(RefMut::map(os_handle.dir.borrow_mut(), |dir| {
|
||||
dir.as_mut().unwrap()
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::cell::RefCell;
|
||||
use std::fs;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::ops::Deref;
|
||||
use std::os::unix::prelude::{AsRawFd, RawFd};
|
||||
use std::sync::Mutex;
|
||||
use yanix::dir::Dir;
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -18,12 +18,15 @@ pub(crate) struct OsHandle {
|
||||
// > of the DIR pointer, dirp, from which they are derived.
|
||||
// > If the directory is closed and then reopened, prior values
|
||||
// > returned by telldir() will no longer be valid.
|
||||
pub(crate) dir: Option<Mutex<Dir>>,
|
||||
pub(crate) dir: RefCell<Option<Dir>>,
|
||||
}
|
||||
|
||||
impl From<fs::File> for OsHandle {
|
||||
fn from(file: fs::File) -> Self {
|
||||
Self { file, dir: None }
|
||||
Self {
|
||||
file,
|
||||
dir: RefCell::new(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,9 +43,3 @@ impl Deref for OsHandle {
|
||||
&self.file
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for OsHandle {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.file
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ pub(crate) fn filestat_get(file: &std::fs::File) -> Result<types::Filestat> {
|
||||
}
|
||||
|
||||
pub(crate) fn readdir<'a>(
|
||||
os_handle: &'a mut OsHandle,
|
||||
os_handle: &'a OsHandle,
|
||||
cookie: types::Dircookie,
|
||||
) -> Result<impl Iterator<Item = Result<(types::Dirent, String)>> + 'a> {
|
||||
use yanix::dir::{DirIter, Entry, EntryExt, SeekLoc};
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::sys::entry::OsHandle;
|
||||
use crate::wasi::Result;
|
||||
use yanix::dir::Dir;
|
||||
|
||||
pub(crate) fn get_dir_from_os_handle(os_handle: &mut OsHandle) -> Result<Box<Dir>> {
|
||||
pub(crate) fn get_dir_from_os_handle(os_handle: &OsHandle) -> Result<Box<Dir>> {
|
||||
// We need to duplicate the fd, because `opendir(3)`:
|
||||
// After a successful call to fdopendir(), fd is used internally by the implementation,
|
||||
// and should not otherwise be used by the application.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::fs;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::ops::Deref;
|
||||
use std::os::unix::prelude::{AsRawFd, RawFd};
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -24,9 +24,3 @@ impl Deref for OsHandle {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for OsHandle {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::wasi::{types, RightsExt};
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::ops::Deref;
|
||||
use std::os::windows::prelude::{AsRawHandle, FromRawHandle, RawHandle};
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -29,12 +29,6 @@ impl Deref for OsHandle {
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for OsHandle {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawHandle for Descriptor {
|
||||
fn as_raw_handle(&self) -> RawHandle {
|
||||
match self {
|
||||
|
||||
Reference in New Issue
Block a user