diff --git a/cli/ops/process.rs b/cli/ops/process.rs index 9801478324..e84418a685 100644 --- a/cli/ops/process.rs +++ b/cli/ops/process.rs @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use super::dispatch_json::{Deserialize, JsonOp, Value}; -use super::io::{StreamResource, StreamResourceHolder}; +use super::io::{std_file_resource, StreamResource, StreamResourceHolder}; use crate::op_error::OpError; use crate::signal::kill; use crate::state::State; @@ -22,19 +22,11 @@ pub fn init(i: &mut Isolate, s: &State) { fn clone_file(rid: u32, state: &State) -> Result { let mut state = state.borrow_mut(); - let repr_holder = state - .resource_table - .get_mut::(rid) - .ok_or_else(OpError::bad_resource_id)?; - match repr_holder.resource { - StreamResource::FsFile(Some((ref mut file, _))) => { - let tokio_file = futures::executor::block_on(file.try_clone())?; - let std_file = futures::executor::block_on(tokio_file.into_std()); - Ok(std_file) - } - StreamResource::FsFile(None) => Err(OpError::resource_unavailable()), - _ => Err(OpError::bad_resource_id()), - } + + std_file_resource(&mut state.resource_table, rid, move |r| match r { + Ok(std_file) => std_file.try_clone().map_err(OpError::from), + Err(_) => Err(OpError::bad_resource_id()), + }) } fn subprocess_stdio_map(s: &str) -> std::process::Stdio { diff --git a/cli/ops/tty.rs b/cli/ops/tty.rs index 461c1ca303..90fa2bde39 100644 --- a/cli/ops/tty.rs +++ b/cli/ops/tty.rs @@ -65,22 +65,41 @@ pub fn op_set_raw( use winapi::shared::minwindef::FALSE; use winapi::um::{consoleapi, handleapi}; - let state = state_.borrow_mut(); - let resource_holder = state.resource_table.get::(rid); + let mut state = state_.borrow_mut(); + let resource_holder = + state.resource_table.get_mut::(rid); if resource_holder.is_none() { return Err(OpError::bad_resource_id()); } + let resource_holder = resource_holder.unwrap(); // For now, only stdin. - let handle = match &resource_holder.unwrap().resource { + let handle = match &mut resource_holder.resource { StreamResource::Stdin(_, _) => std::io::stdin().as_raw_handle(), - StreamResource::FsFile(None) => { - return Err(OpError::resource_unavailable()) - } - StreamResource::FsFile(Some((f, _))) => { - let tokio_file = futures::executor::block_on(f.try_clone())?; - let std_file = futures::executor::block_on(tokio_file.into_std()); - std_file.as_raw_handle() + StreamResource::FsFile(ref mut option_file_metadata) => { + if let Some((tokio_file, metadata)) = option_file_metadata.take() { + 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); + resource_holder.resource = + StreamResource::FsFile(Some((tokio_file, metadata))); + // return the result. + raw_handle + } + Err(tokio_file) => { + // This function will return an error containing the file if + // some operation is in-flight. + resource_holder.resource = + StreamResource::FsFile(Some((tokio_file, metadata))); + return Err(OpError::resource_unavailable()); + } + } + } else { + return Err(OpError::resource_unavailable()); + } } _ => { return Err(OpError::bad_resource_id()); @@ -127,9 +146,7 @@ pub fn op_set_raw( (std::io::stdin().as_raw_fd(), &mut metadata.mode) } StreamResource::FsFile(Some((f, ref mut metadata))) => { - let tokio_file = futures::executor::block_on(f.try_clone())?; - let std_file = futures::executor::block_on(tokio_file.into_std()); - (std_file.as_raw_fd(), &mut metadata.tty.mode) + (f.as_raw_fd(), &mut metadata.tty.mode) } StreamResource::FsFile(None) => { return Err(OpError::resource_unavailable()) @@ -173,9 +190,7 @@ pub fn op_set_raw( (std::io::stdin().as_raw_fd(), &mut metadata.mode) } StreamResource::FsFile(Some((f, ref mut metadata))) => { - let tokio_file = futures::executor::block_on(f.try_clone())?; - let std_file = futures::executor::block_on(tokio_file.into_std()); - (std_file.as_raw_fd(), &mut metadata.tty.mode) + (f.as_raw_fd(), &mut metadata.tty.mode) } StreamResource::FsFile(None) => { return Err(OpError::resource_unavailable()); diff --git a/cli/worker.rs b/cli/worker.rs index c2a1ecc576..bbddf91d24 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -270,17 +270,8 @@ mod tests { use crate::startup_data; use crate::state::State; use crate::tokio_util; - use futures::executor::block_on; use std::sync::atomic::Ordering; - pub fn run_in_task(f: F) - where - F: FnOnce() + Send + 'static, - { - let fut = futures::future::lazy(move |_cx| f()); - tokio_util::run_basic(fut) - } - #[test] fn execute_mod_esm_imports_a() { let p = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) @@ -405,32 +396,28 @@ mod tests { worker } - #[test] - fn execute_mod_resolve_error() { - run_in_task(|| { - // "foo" is not a valid module specifier so this should return an error. - let mut worker = create_test_worker(); - let module_specifier = - ModuleSpecifier::resolve_url_or_path("does-not-exist").unwrap(); - let result = block_on(worker.execute_module(&module_specifier)); - assert!(result.is_err()); - }) + #[tokio::test] + async fn execute_mod_resolve_error() { + // "foo" is not a valid module specifier so this should return an error. + let mut worker = create_test_worker(); + let module_specifier = + ModuleSpecifier::resolve_url_or_path("does-not-exist").unwrap(); + let result = worker.execute_module(&module_specifier).await; + assert!(result.is_err()); } - #[test] - fn execute_mod_002_hello() { - run_in_task(|| { - // This assumes cwd is project root (an assumption made throughout the - // tests). - let mut worker = create_test_worker(); - let p = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) - .parent() - .unwrap() - .join("cli/tests/002_hello.ts"); - let module_specifier = - ModuleSpecifier::resolve_url_or_path(&p.to_string_lossy()).unwrap(); - let result = block_on(worker.execute_module(&module_specifier)); - assert!(result.is_ok()); - }) + #[tokio::test] + async fn execute_mod_002_hello() { + // This assumes cwd is project root (an assumption made throughout the + // tests). + let mut worker = create_test_worker(); + let p = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .parent() + .unwrap() + .join("cli/tests/002_hello.ts"); + let module_specifier = + ModuleSpecifier::resolve_url_or_path(&p.to_string_lossy()).unwrap(); + let result = worker.execute_module(&module_specifier).await; + assert!(result.is_ok()); } }