1
0
Fork 0
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:
Casper Beyer 2021-01-09 00:55:17 +08:00 committed by GitHub
parent 5f015eac9c
commit 9cf82d3c66
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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)]