summaryrefslogtreecommitdiff
path: root/runtime/ops
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/ops')
-rw-r--r--runtime/ops/fs.rs130
-rw-r--r--runtime/ops/io.rs89
-rw-r--r--runtime/ops/tty.rs43
3 files changed, 105 insertions, 157 deletions
diff --git a/runtime/ops/fs.rs b/runtime/ops/fs.rs
index 3e174e00b..ddd7f9ca2 100644
--- a/runtime/ops/fs.rs
+++ b/runtime/ops/fs.rs
@@ -15,7 +15,6 @@ use deno_core::ZeroCopyBuf;
use deno_core::Extension;
use deno_core::OpState;
-use deno_core::RcRef;
use deno_core::ResourceId;
use deno_crypto::rand::thread_rng;
use deno_crypto::rand::Rng;
@@ -32,7 +31,6 @@ use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::time::SystemTime;
use std::time::UNIX_EPOCH;
-use tokio::io::AsyncSeekExt;
#[cfg(not(unix))]
use deno_core::error::generic_error;
@@ -172,8 +170,7 @@ fn op_open_sync(
let std_file = open_options.open(&path).map_err(|err| {
Error::new(err.kind(), format!("{}, open '{}'", err, path.display()))
})?;
- let tokio_file = tokio::fs::File::from_std(std_file);
- let resource = StdFileResource::fs_file(tokio_file);
+ let resource = StdFileResource::fs_file(std_file);
let rid = state.resource_table.add(resource);
Ok(rid)
}
@@ -184,14 +181,13 @@ async fn op_open_async(
args: OpenArgs,
) -> Result<ResourceId, AnyError> {
let (path, open_options) = open_helper(&mut state.borrow_mut(), &args)?;
- let tokio_file = tokio::fs::OpenOptions::from(open_options)
- .open(&path)
- .await
- .map_err(|err| {
+ let std_file = tokio::task::spawn_blocking(move || {
+ open_options.open(path.clone()).map_err(|err| {
Error::new(err.kind(), format!("{}, open '{}'", err, path.display()))
- })?;
-
- let resource = StdFileResource::fs_file(tokio_file);
+ })
+ })
+ .await?;
+ let resource = StdFileResource::fs_file(std_file?);
let rid = state.borrow_mut().resource_table.add(resource);
Ok(rid)
}
@@ -342,12 +338,15 @@ async fn op_seek_async(
return Err(bad_resource_id());
}
- let mut fs_file = RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap())
- .borrow_mut()
- .await;
+ let fs_file = resource.fs_file.as_ref().unwrap();
+ let std_file = fs_file.0.as_ref().unwrap().clone();
- let pos = (*fs_file).0.as_mut().unwrap().seek(seek_from).await?;
- Ok(pos)
+ tokio::task::spawn_blocking(move || {
+ let mut std_file = std_file.lock().unwrap();
+ std_file.seek(seek_from)
+ })
+ .await?
+ .map_err(AnyError::from)
}
#[op]
@@ -376,12 +375,15 @@ async fn op_fdatasync_async(
return Err(bad_resource_id());
}
- let mut fs_file = RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap())
- .borrow_mut()
- .await;
+ let fs_file = resource.fs_file.as_ref().unwrap();
+ let std_file = fs_file.0.as_ref().unwrap().clone();
- (*fs_file).0.as_mut().unwrap().sync_data().await?;
- Ok(())
+ tokio::task::spawn_blocking(move || {
+ let std_file = std_file.lock().unwrap();
+ std_file.sync_data()
+ })
+ .await?
+ .map_err(AnyError::from)
}
#[op]
@@ -407,12 +409,15 @@ async fn op_fsync_async(
return Err(bad_resource_id());
}
- let mut fs_file = RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap())
- .borrow_mut()
- .await;
+ let fs_file = resource.fs_file.as_ref().unwrap();
+ let std_file = fs_file.0.as_ref().unwrap().clone();
- (*fs_file).0.as_mut().unwrap().sync_all().await?;
- Ok(())
+ tokio::task::spawn_blocking(move || {
+ let std_file = std_file.lock().unwrap();
+ std_file.sync_all()
+ })
+ .await?
+ .map_err(AnyError::from)
}
#[op]
@@ -441,11 +446,15 @@ async fn op_fstat_async(
return Err(bad_resource_id());
}
- let mut fs_file = RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap())
- .borrow_mut()
- .await;
+ let fs_file = resource.fs_file.as_ref().unwrap();
+ let std_file = fs_file.0.as_ref().unwrap().clone();
- let metadata = (*fs_file).0.as_mut().unwrap().metadata().await?;
+ let metadata = tokio::task::spawn_blocking(move || {
+ let std_file = std_file.lock().unwrap();
+ std_file.metadata()
+ })
+ .await?
+ .map_err(AnyError::from)?;
Ok(get_stat(metadata))
}
@@ -489,19 +498,11 @@ async fn op_flock_async(
return Err(bad_resource_id());
}
- let mut fs_file = RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap())
- .borrow_mut()
- .await;
-
- let std_file = (*fs_file)
- .0
- .as_mut()
- .unwrap()
- .try_clone()
- .await?
- .into_std()
- .await;
+ let fs_file = resource.fs_file.as_ref().unwrap();
+ let std_file = fs_file.0.as_ref().unwrap().clone();
+
tokio::task::spawn_blocking(move || -> Result<(), AnyError> {
+ let std_file = std_file.lock().unwrap();
if exclusive {
std_file.lock_exclusive()?;
} else {
@@ -546,19 +547,11 @@ async fn op_funlock_async(
return Err(bad_resource_id());
}
- let mut fs_file = RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap())
- .borrow_mut()
- .await;
-
- let std_file = (*fs_file)
- .0
- .as_mut()
- .unwrap()
- .try_clone()
- .await?
- .into_std()
- .await;
+ let fs_file = resource.fs_file.as_ref().unwrap();
+ let std_file = fs_file.0.as_ref().unwrap().clone();
+
tokio::task::spawn_blocking(move || -> Result<(), AnyError> {
+ let std_file = std_file.lock().unwrap();
std_file.unlock()?;
Ok(())
})
@@ -1642,12 +1635,15 @@ async fn op_ftruncate_async(
return Err(bad_resource_id());
}
- let mut fs_file = RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap())
- .borrow_mut()
- .await;
+ let fs_file = resource.fs_file.as_ref().unwrap();
+ let std_file = fs_file.0.as_ref().unwrap().clone();
- (*fs_file).0.as_mut().unwrap().set_len(len).await?;
- Ok(())
+ tokio::task::spawn_blocking(move || {
+ let std_file = std_file.lock().unwrap();
+ std_file.set_len(len)
+ })
+ .await?
+ .map_err(AnyError::from)
}
#[derive(Deserialize)]
@@ -1941,20 +1937,10 @@ async fn op_futime_async(
return Err(bad_resource_id());
}
- let mut fs_file = RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap())
- .borrow_mut()
- .await;
-
- let std_file = (*fs_file)
- .0
- .as_mut()
- .unwrap()
- .try_clone()
- .await?
- .into_std()
- .await;
-
+ let fs_file = resource.fs_file.as_ref().unwrap();
+ let std_file = fs_file.0.as_ref().unwrap().clone();
tokio::task::spawn_blocking(move || {
+ let std_file = std_file.lock().unwrap();
filetime::set_file_handle_times(&std_file, Some(atime), Some(mtime))?;
Ok(())
})
diff --git a/runtime/ops/io.rs b/runtime/ops/io.rs
index 35dddaac2..6db5d69a9 100644
--- a/runtime/ops/io.rs
+++ b/runtime/ops/io.rs
@@ -17,10 +17,13 @@ use deno_core::ResourceId;
use deno_core::ZeroCopyBuf;
use once_cell::sync::Lazy;
use std::borrow::Cow;
+use std::cell::RefCell;
use std::fs::File as StdFile;
use std::io::Read;
use std::io::Write;
use std::rc::Rc;
+use std::sync::Arc;
+use std::sync::Mutex;
use tokio::io::AsyncRead;
use tokio::io::AsyncReadExt;
use tokio::io::AsyncWrite;
@@ -225,10 +228,11 @@ impl Resource for ChildStderrResource {
}
}
-#[derive(Debug, Default)]
+type MaybeSharedStdFile = Option<Arc<Mutex<StdFile>>>;
+
+#[derive(Default)]
pub struct StdFileResource {
- pub fs_file:
- Option<AsyncRefCell<(Option<tokio::fs::File>, Option<FileMetadata>)>>,
+ pub fs_file: Option<(MaybeSharedStdFile, Option<RefCell<FileMetadata>>)>,
cancel: CancelHandle,
name: String,
}
@@ -236,21 +240,21 @@ pub struct StdFileResource {
impl StdFileResource {
pub fn stdio(std_file: &StdFile, name: &str) -> Self {
Self {
- fs_file: Some(AsyncRefCell::new((
- std_file.try_clone().map(tokio::fs::File::from_std).ok(),
- Some(FileMetadata::default()),
- ))),
+ fs_file: Some((
+ std_file.try_clone().map(|s| Arc::new(Mutex::new(s))).ok(),
+ Some(RefCell::new(FileMetadata::default())),
+ )),
name: name.to_string(),
..Default::default()
}
}
- pub fn fs_file(fs_file: tokio::fs::File) -> Self {
+ pub fn fs_file(fs_file: StdFile) -> Self {
Self {
- fs_file: Some(AsyncRefCell::new((
- Some(fs_file),
- Some(FileMetadata::default()),
- ))),
+ fs_file: Some((
+ Some(Arc::new(Mutex::new(fs_file))),
+ Some(RefCell::new(FileMetadata::default())),
+ )),
name: "fsFile".to_string(),
..Default::default()
}
@@ -261,11 +265,14 @@ impl StdFileResource {
mut buf: ZeroCopyBuf,
) -> Result<usize, AnyError> {
if self.fs_file.is_some() {
- let mut fs_file = RcRef::map(&self, |r| r.fs_file.as_ref().unwrap())
- .borrow_mut()
- .await;
- let nwritten = fs_file.0.as_mut().unwrap().read(&mut buf).await?;
- Ok(nwritten)
+ let fs_file = self.fs_file.as_ref().unwrap();
+ let std_file = fs_file.0.as_ref().unwrap().clone();
+ tokio::task::spawn_blocking(move || {
+ let mut std_file = std_file.lock().unwrap();
+ std_file.read(&mut buf)
+ })
+ .await?
+ .map_err(AnyError::from)
} else {
Err(resource_unavailable())
}
@@ -273,12 +280,14 @@ impl StdFileResource {
async fn write(self: Rc<Self>, buf: ZeroCopyBuf) -> Result<usize, AnyError> {
if self.fs_file.is_some() {
- let mut fs_file = RcRef::map(&self, |r| r.fs_file.as_ref().unwrap())
- .borrow_mut()
- .await;
- let nwritten = fs_file.0.as_mut().unwrap().write(&buf).await?;
- fs_file.0.as_mut().unwrap().flush().await?;
- Ok(nwritten)
+ let fs_file = self.fs_file.as_ref().unwrap();
+ let std_file = fs_file.0.as_ref().unwrap().clone();
+ tokio::task::spawn_blocking(move || {
+ let mut std_file = std_file.lock().unwrap();
+ std_file.write(&buf)
+ })
+ .await?
+ .map_err(AnyError::from)
} else {
Err(resource_unavailable())
}
@@ -292,42 +301,18 @@ impl StdFileResource {
where
F: FnMut(Result<&mut std::fs::File, ()>) -> Result<R, AnyError>,
{
- // First we look up the rid in the resource table.
let resource = state.resource_table.get::<StdFileResource>(rid)?;
-
+ // TODO(@AaronO): does this make sense ?
// Sync write only works for FsFile. It doesn't make sense to do this
// for non-blocking sockets. So we error out if not FsFile.
if resource.fs_file.is_none() {
return f(Err(()));
}
- // The object in the resource table is a tokio::fs::File - but in
- // order to do a blocking write on it, we must turn it into a
- // std::fs::File. Hopefully this code compiles down to nothing.
- let fs_file_resource =
- RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap()).try_borrow_mut();
-
- if let Some(mut fs_file) = fs_file_resource {
- let tokio_file = fs_file.0.take().unwrap();
- match tokio_file.try_into_std() {
- Ok(mut std_file) => {
- let result = f(Ok(&mut std_file));
- // Turn the std_file handle back into a tokio file, put it back
- // in the resource table.
- let tokio_file = tokio::fs::File::from_std(std_file);
- fs_file.0 = Some(tokio_file);
- // return the result.
- result
- }
- Err(tokio_file) => {
- // This function will return an error containing the file if
- // some operation is in-flight.
- fs_file.0 = Some(tokio_file);
- Err(resource_unavailable())
- }
- }
- } else {
- Err(resource_unavailable())
+ let (r, _) = resource.fs_file.as_ref().unwrap();
+ match r {
+ Some(r) => f(Ok(&mut r.as_ref().lock().unwrap())),
+ None => Err(resource_unavailable()),
}
}
}
diff --git a/runtime/ops/tty.rs b/runtime/ops/tty.rs
index 465fb1679..789847697 100644
--- a/runtime/ops/tty.rs
+++ b/runtime/ops/tty.rs
@@ -8,7 +8,6 @@ use deno_core::error::AnyError;
use deno_core::op;
use deno_core::Extension;
use deno_core::OpState;
-use deno_core::RcRef;
use deno_core::ResourceId;
use serde::Deserialize;
use serde::Serialize;
@@ -96,28 +95,11 @@ fn op_set_raw(state: &mut OpState, args: SetRawArgs) -> Result<(), AnyError> {
return Err(bad_resource_id());
}
- let fs_file_resource =
- RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap()).try_borrow_mut();
-
- let handle_result = if let Some(mut fs_file) = fs_file_resource {
- let tokio_file = fs_file.0.take().unwrap();
- match tokio_file.try_into_std() {
- Ok(std_file) => {
- let raw_handle = std_file.as_raw_handle();
- // Turn the std_file handle back into a tokio file, put it back
- // in the resource table.
- let tokio_file = tokio::fs::File::from_std(std_file);
- fs_file.0 = Some(tokio_file);
- // return the result.
- Ok(raw_handle)
- }
- Err(tokio_file) => {
- // This function will return an error containing the file if
- // some operation is in-flight.
- fs_file.0 = Some(tokio_file);
- Err(resource_unavailable())
- }
- }
+ let handle_result = if let Some((fs_file, _)) = &resource.fs_file {
+ let file = fs_file.as_ref().unwrap().clone();
+ let std_file = file.lock().unwrap();
+ let raw_handle = std_file.as_raw_handle();
+ Ok(raw_handle)
} else {
Err(resource_unavailable())
};
@@ -156,20 +138,15 @@ fn op_set_raw(state: &mut OpState, args: SetRawArgs) -> Result<(), AnyError> {
return Err(not_supported());
}
- let maybe_fs_file_resource =
- RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap()).try_borrow_mut();
-
- if maybe_fs_file_resource.is_none() {
- return Err(resource_unavailable());
- }
+ let (fs_file, meta) =
+ resource.fs_file.as_ref().ok_or_else(resource_unavailable)?;
- let mut fs_file_resource = maybe_fs_file_resource.unwrap();
- if fs_file_resource.0.is_none() {
+ if fs_file.is_none() {
return Err(resource_unavailable());
}
- let raw_fd = fs_file_resource.0.as_ref().unwrap().as_raw_fd();
- let maybe_tty_mode = &mut fs_file_resource.1.as_mut().unwrap().tty.mode;
+ let raw_fd = fs_file.as_ref().unwrap().lock().unwrap().as_raw_fd();
+ let maybe_tty_mode = &mut meta.as_ref().unwrap().borrow_mut().tty.mode;
if is_raw {
if maybe_tty_mode.is_none() {