mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 07:14:47 -05:00
fix(runtime): use tokio for async fs ops (#9042)
This commit makes following ops async: - op_fstat_async - op_ftruncate_async - op_seek_async - op_fdatasync_async - op_fsync_async - op_futime_async
This commit is contained in:
parent
5f015eac9c
commit
9cf82d3c66
1 changed files with 112 additions and 40 deletions
|
@ -4,6 +4,7 @@ use super::io::std_file_resource;
|
||||||
use super::io::StreamResource;
|
use super::io::StreamResource;
|
||||||
use crate::fs_util::canonicalize_path;
|
use crate::fs_util::canonicalize_path;
|
||||||
use crate::permissions::Permissions;
|
use crate::permissions::Permissions;
|
||||||
|
use deno_core::error::bad_resource_id;
|
||||||
use deno_core::error::custom_error;
|
use deno_core::error::custom_error;
|
||||||
use deno_core::error::type_error;
|
use deno_core::error::type_error;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
@ -12,6 +13,7 @@ use deno_core::serde_json::json;
|
||||||
use deno_core::serde_json::Value;
|
use deno_core::serde_json::Value;
|
||||||
use deno_core::BufVec;
|
use deno_core::BufVec;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
|
use deno_core::RcRef;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
use deno_crypto::rand::thread_rng;
|
use deno_crypto::rand::thread_rng;
|
||||||
use deno_crypto::rand::Rng;
|
use deno_crypto::rand::Rng;
|
||||||
|
@ -251,14 +253,22 @@ async fn op_seek_async(
|
||||||
_zero_copy: BufVec,
|
_zero_copy: BufVec,
|
||||||
) -> Result<Value, AnyError> {
|
) -> Result<Value, AnyError> {
|
||||||
let (rid, seek_from) = seek_helper(args)?;
|
let (rid, seek_from) = seek_helper(args)?;
|
||||||
// TODO(ry) This is a fake async op. We need to use poll_fn,
|
|
||||||
// tokio::fs::File::start_seek and tokio::fs::File::poll_complete
|
let resource = state
|
||||||
let pos = std_file_resource(&mut state.borrow_mut(), rid, |r| match r {
|
.borrow_mut()
|
||||||
Ok(std_file) => std_file.seek(seek_from).map_err(AnyError::from),
|
.resource_table
|
||||||
Err(_) => Err(type_error(
|
.get::<StreamResource>(rid)
|
||||||
"cannot seek on this type of resource".to_string(),
|
.ok_or_else(bad_resource_id)?;
|
||||||
)),
|
|
||||||
})?;
|
if resource.fs_file.is_none() {
|
||||||
|
return Err(bad_resource_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut fs_file = RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap())
|
||||||
|
.borrow_mut()
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let pos = (*fs_file).0.as_mut().unwrap().seek(seek_from).await?;
|
||||||
Ok(json!(pos))
|
Ok(json!(pos))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,10 +299,22 @@ async fn op_fdatasync_async(
|
||||||
) -> Result<Value, AnyError> {
|
) -> Result<Value, AnyError> {
|
||||||
let args: FdatasyncArgs = serde_json::from_value(args)?;
|
let args: FdatasyncArgs = serde_json::from_value(args)?;
|
||||||
let rid = args.rid as u32;
|
let rid = args.rid as u32;
|
||||||
std_file_resource(&mut state.borrow_mut(), rid, |r| match r {
|
|
||||||
Ok(std_file) => std_file.sync_data().map_err(AnyError::from),
|
let resource = state
|
||||||
Err(_) => Err(type_error("cannot sync this type of resource".to_string())),
|
.borrow_mut()
|
||||||
})?;
|
.resource_table
|
||||||
|
.get::<StreamResource>(rid)
|
||||||
|
.ok_or_else(bad_resource_id)?;
|
||||||
|
|
||||||
|
if resource.fs_file.is_none() {
|
||||||
|
return Err(bad_resource_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut fs_file = RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap())
|
||||||
|
.borrow_mut()
|
||||||
|
.await;
|
||||||
|
|
||||||
|
(*fs_file).0.as_mut().unwrap().sync_data().await?;
|
||||||
Ok(json!({}))
|
Ok(json!({}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,10 +345,22 @@ async fn op_fsync_async(
|
||||||
) -> Result<Value, AnyError> {
|
) -> Result<Value, AnyError> {
|
||||||
let args: FsyncArgs = serde_json::from_value(args)?;
|
let args: FsyncArgs = serde_json::from_value(args)?;
|
||||||
let rid = args.rid as u32;
|
let rid = args.rid as u32;
|
||||||
std_file_resource(&mut state.borrow_mut(), rid, |r| match r {
|
|
||||||
Ok(std_file) => std_file.sync_all().map_err(AnyError::from),
|
let resource = state
|
||||||
Err(_) => Err(type_error("cannot sync this type of resource".to_string())),
|
.borrow_mut()
|
||||||
})?;
|
.resource_table
|
||||||
|
.get::<StreamResource>(rid)
|
||||||
|
.ok_or_else(bad_resource_id)?;
|
||||||
|
|
||||||
|
if resource.fs_file.is_none() {
|
||||||
|
return Err(bad_resource_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut fs_file = RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap())
|
||||||
|
.borrow_mut()
|
||||||
|
.await;
|
||||||
|
|
||||||
|
(*fs_file).0.as_mut().unwrap().sync_all().await?;
|
||||||
Ok(json!({}))
|
Ok(json!({}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,13 +394,22 @@ async fn op_fstat_async(
|
||||||
|
|
||||||
let args: FstatArgs = serde_json::from_value(args)?;
|
let args: FstatArgs = serde_json::from_value(args)?;
|
||||||
let rid = args.rid as u32;
|
let rid = args.rid as u32;
|
||||||
let metadata =
|
|
||||||
std_file_resource(&mut state.borrow_mut(), rid, |r| match r {
|
let resource = state
|
||||||
Ok(std_file) => std_file.metadata().map_err(AnyError::from),
|
.borrow_mut()
|
||||||
Err(_) => {
|
.resource_table
|
||||||
Err(type_error("cannot stat this type of resource".to_string()))
|
.get::<StreamResource>(rid)
|
||||||
}
|
.ok_or_else(bad_resource_id)?;
|
||||||
})?;
|
|
||||||
|
if resource.fs_file.is_none() {
|
||||||
|
return Err(bad_resource_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut fs_file = RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap())
|
||||||
|
.borrow_mut()
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let metadata = (*fs_file).0.as_mut().unwrap().metadata().await?;
|
||||||
Ok(get_stat_json(metadata))
|
Ok(get_stat_json(metadata))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1337,10 +1380,22 @@ async fn op_ftruncate_async(
|
||||||
let args: FtruncateArgs = serde_json::from_value(args)?;
|
let args: FtruncateArgs = serde_json::from_value(args)?;
|
||||||
let rid = args.rid as u32;
|
let rid = args.rid as u32;
|
||||||
let len = args.len as u64;
|
let len = args.len as u64;
|
||||||
std_file_resource(&mut state.borrow_mut(), rid, |r| match r {
|
|
||||||
Ok(std_file) => std_file.set_len(len).map_err(AnyError::from),
|
let resource = state
|
||||||
Err(_) => Err(type_error("cannot truncate this type of resource")),
|
.borrow_mut()
|
||||||
})?;
|
.resource_table
|
||||||
|
.get::<StreamResource>(rid)
|
||||||
|
.ok_or_else(bad_resource_id)?;
|
||||||
|
|
||||||
|
if resource.fs_file.is_none() {
|
||||||
|
return Err(bad_resource_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut fs_file = RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap())
|
||||||
|
.borrow_mut()
|
||||||
|
.await;
|
||||||
|
|
||||||
|
(*fs_file).0.as_mut().unwrap().set_len(len).await?;
|
||||||
Ok(json!({}))
|
Ok(json!({}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1610,24 +1665,41 @@ async fn op_futime_async(
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: BufVec,
|
_zero_copy: BufVec,
|
||||||
) -> Result<Value, AnyError> {
|
) -> Result<Value, AnyError> {
|
||||||
let mut state = state.borrow_mut();
|
super::check_unstable2(&state, "Deno.futime");
|
||||||
super::check_unstable(&state, "Deno.futime");
|
|
||||||
let args: FutimeArgs = serde_json::from_value(args)?;
|
let args: FutimeArgs = serde_json::from_value(args)?;
|
||||||
let rid = args.rid as u32;
|
let rid = args.rid as u32;
|
||||||
let atime = filetime::FileTime::from_unix_time(args.atime.0, args.atime.1);
|
let atime = filetime::FileTime::from_unix_time(args.atime.0, args.atime.1);
|
||||||
let mtime = filetime::FileTime::from_unix_time(args.mtime.0, args.mtime.1);
|
let mtime = filetime::FileTime::from_unix_time(args.mtime.0, args.mtime.1);
|
||||||
// TODO Not actually async! https://github.com/denoland/deno/issues/7400
|
|
||||||
std_file_resource(&mut state, rid, |r| match r {
|
|
||||||
Ok(std_file) => {
|
|
||||||
filetime::set_file_handle_times(std_file, Some(atime), Some(mtime))
|
|
||||||
.map_err(AnyError::from)
|
|
||||||
}
|
|
||||||
Err(_) => Err(type_error(
|
|
||||||
"cannot futime on this type of resource".to_string(),
|
|
||||||
)),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(json!({}))
|
let resource = state
|
||||||
|
.borrow_mut()
|
||||||
|
.resource_table
|
||||||
|
.get::<StreamResource>(rid)
|
||||||
|
.ok_or_else(bad_resource_id)?;
|
||||||
|
|
||||||
|
if resource.fs_file.is_none() {
|
||||||
|
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;
|
||||||
|
|
||||||
|
tokio::task::spawn_blocking(move || {
|
||||||
|
filetime::set_file_handle_times(&std_file, Some(atime), Some(mtime))?;
|
||||||
|
Ok(json!({}))
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
|
Loading…
Reference in a new issue