diff options
Diffstat (limited to 'cli/ops')
-rw-r--r-- | cli/ops/dispatch_flatbuffers.rs | 128 | ||||
-rw-r--r-- | cli/ops/dispatch_minimal.rs | 8 | ||||
-rw-r--r-- | cli/ops/files.rs | 90 | ||||
-rw-r--r-- | cli/ops/mod.rs | 3 |
4 files changed, 5 insertions, 224 deletions
diff --git a/cli/ops/dispatch_flatbuffers.rs b/cli/ops/dispatch_flatbuffers.rs deleted file mode 100644 index edec77703..000000000 --- a/cli/ops/dispatch_flatbuffers.rs +++ /dev/null @@ -1,128 +0,0 @@ -use super::utils::CliOpResult; -use crate::deno_error::GetErrorKind; -use crate::msg; -use crate::state::ThreadSafeState; -use deno::*; -use flatbuffers::FlatBufferBuilder; -use hyper::rt::Future; - -type CliDispatchFn = fn( - state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option<PinnedBuf>, -) -> CliOpResult; - -use super::files::{op_read, op_write}; - -/// Processes raw messages from JavaScript. -/// This functions invoked every time Deno.core.dispatch() is called. -/// control corresponds to the first argument of Deno.core.dispatch(). -/// data corresponds to the second argument of Deno.core.dispatch(). -pub fn dispatch( - state: &ThreadSafeState, - control: &[u8], - zero_copy: Option<PinnedBuf>, -) -> CoreOp { - let base = msg::get_root_as_base(&control); - let inner_type = base.inner_type(); - let is_sync = base.sync(); - let cmd_id = base.cmd_id(); - - debug!( - "msg_from_js {} sync {}", - msg::enum_name_any(inner_type), - is_sync - ); - - let op_func: CliDispatchFn = match op_selector_std(inner_type) { - Some(v) => v, - None => panic!("Unhandled message {}", msg::enum_name_any(inner_type)), - }; - - let op_result = op_func(state, &base, zero_copy); - - match op_result { - Ok(Op::Sync(buf)) => Op::Sync(buf), - Ok(Op::Async(fut)) => { - let result_fut = Box::new( - fut - .or_else(move |err: ErrBox| -> Result<Buf, ()> { - debug!("op err {}", err); - // No matter whether we got an Err or Ok, we want a serialized message to - // send back. So transform the DenoError into a Buf. - let builder = &mut FlatBufferBuilder::new(); - let errmsg_offset = builder.create_string(&format!("{}", err)); - Ok(serialize_response( - cmd_id, - builder, - msg::BaseArgs { - error: Some(errmsg_offset), - error_kind: err.kind(), - ..Default::default() - }, - )) - }) - .and_then(move |buf: Buf| -> Result<Buf, ()> { - // Handle empty responses. For sync responses we just want - // to send null. For async we want to send a small message - // with the cmd_id. - let buf = if buf.len() > 0 { - buf - } else { - let builder = &mut FlatBufferBuilder::new(); - serialize_response( - cmd_id, - builder, - msg::BaseArgs { - ..Default::default() - }, - ) - }; - Ok(buf) - }) - .map_err(|err| panic!("unexpected error {:?}", err)), - ); - Op::Async(result_fut) - } - Err(err) => { - debug!("op err {}", err); - // No matter whether we got an Err or Ok, we want a serialized message to - // send back. So transform the DenoError into a Buf. - let builder = &mut FlatBufferBuilder::new(); - let errmsg_offset = builder.create_string(&format!("{}", err)); - let response_buf = serialize_response( - cmd_id, - builder, - msg::BaseArgs { - error: Some(errmsg_offset), - error_kind: err.kind(), - ..Default::default() - }, - ); - Op::Sync(response_buf) - } - } -} - -pub fn serialize_response( - cmd_id: u32, - builder: &mut FlatBufferBuilder<'_>, - mut args: msg::BaseArgs<'_>, -) -> Buf { - args.cmd_id = cmd_id; - let base = msg::Base::create(builder, &args); - msg::finish_base_buffer(builder, base); - let data = builder.finished_data(); - // println!("serialize_response {:x?}", data); - data.into() -} - -/// Standard ops set for most isolates -pub fn op_selector_std(inner_type: msg::Any) -> Option<CliDispatchFn> { - match inner_type { - msg::Any::Read => Some(op_read), - msg::Any::Write => Some(op_write), - - _ => None, - } -} diff --git a/cli/ops/dispatch_minimal.rs b/cli/ops/dispatch_minimal.rs index 22d0a92f8..f52893951 100644 --- a/cli/ops/dispatch_minimal.rs +++ b/cli/ops/dispatch_minimal.rs @@ -80,9 +80,6 @@ pub fn dispatch( ) -> CoreOp { let mut record = parse_min_record(control).unwrap(); let is_sync = record.promise_id == 0; - // TODO(ry) Currently there aren't any sync minimal ops. This is just a sanity - // check. Remove later. - assert!(!is_sync); let rid = record.arg; let min_op = d(rid, zero_copy); @@ -102,6 +99,11 @@ pub fn dispatch( })); if is_sync { + // Warning! Possible deadlocks can occur if we try to wait for a future + // while in a future. The safe but expensive alternative is to use + // tokio_util::block_on. + // This block is only exercised for readSync and writeSync, which I think + // works since they're simple polling futures. Op::Sync(fut.wait().unwrap()) } else { Op::Async(fut) diff --git a/cli/ops/files.rs b/cli/ops/files.rs index c02a69b9c..4afe00fc0 100644 --- a/cli/ops/files.rs +++ b/cli/ops/files.rs @@ -1,15 +1,10 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -use super::dispatch_flatbuffers::serialize_response; use super::dispatch_json::{Deserialize, JsonOp, Value}; -use super::utils::*; use crate::deno_error; use crate::fs as deno_fs; -use crate::msg; use crate::resources; use crate::state::ThreadSafeState; -use crate::tokio_write; use deno::*; -use flatbuffers::FlatBufferBuilder; use futures::Future; use std; use std::convert::From; @@ -118,91 +113,6 @@ pub fn op_close( } } -pub fn op_read( - _state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option<PinnedBuf>, -) -> CliOpResult { - let cmd_id = base.cmd_id(); - let inner = base.inner_as_read().unwrap(); - let rid = inner.rid(); - - match resources::lookup(rid) { - None => Err(deno_error::bad_resource()), - Some(resource) => { - let op = tokio::io::read(resource, data.unwrap()) - .map_err(ErrBox::from) - .and_then(move |(_resource, _buf, nread)| { - let builder = &mut FlatBufferBuilder::new(); - let inner = msg::ReadRes::create( - builder, - &msg::ReadResArgs { - nread: nread as u32, - eof: nread == 0, - }, - ); - Ok(serialize_response( - cmd_id, - builder, - msg::BaseArgs { - inner: Some(inner.as_union_value()), - inner_type: msg::Any::ReadRes, - ..Default::default() - }, - )) - }); - if base.sync() { - let buf = op.wait()?; - Ok(Op::Sync(buf)) - } else { - Ok(Op::Async(Box::new(op))) - } - } - } -} - -pub fn op_write( - _state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option<PinnedBuf>, -) -> CliOpResult { - let cmd_id = base.cmd_id(); - let inner = base.inner_as_write().unwrap(); - let rid = inner.rid(); - - match resources::lookup(rid) { - None => Err(deno_error::bad_resource()), - Some(resource) => { - let op = tokio_write::write(resource, data.unwrap()) - .map_err(ErrBox::from) - .and_then(move |(_resource, _buf, nwritten)| { - let builder = &mut FlatBufferBuilder::new(); - let inner = msg::WriteRes::create( - builder, - &msg::WriteResArgs { - nbyte: nwritten as u32, - }, - ); - Ok(serialize_response( - cmd_id, - builder, - msg::BaseArgs { - inner: Some(inner.as_union_value()), - inner_type: msg::Any::WriteRes, - ..Default::default() - }, - )) - }); - if base.sync() { - let buf = op.wait()?; - Ok(Op::Sync(buf)) - } else { - Ok(Op::Async(Box::new(op))) - } - } - } -} - #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct SeekArgs { diff --git a/cli/ops/mod.rs b/cli/ops/mod.rs index 1a853e992..d254f34d2 100644 --- a/cli/ops/mod.rs +++ b/cli/ops/mod.rs @@ -3,7 +3,6 @@ use crate::state::ThreadSafeState; use deno::*; mod compiler; -mod dispatch_flatbuffers; mod dispatch_json; mod dispatch_minimal; mod errors; @@ -26,7 +25,6 @@ mod workers; // Warning! These values are duplicated in the TypeScript code (js/dispatch.ts), // update with care. -pub const OP_FLATBUFFER: OpId = 100; pub const OP_READ: OpId = 1; pub const OP_WRITE: OpId = 2; pub const OP_EXIT: OpId = 3; @@ -296,7 +294,6 @@ pub fn dispatch( dispatch_json::dispatch(fs::op_make_temp_dir, state, control, zero_copy) } OP_CWD => dispatch_json::dispatch(fs::op_cwd, state, control, zero_copy), - OP_FLATBUFFER => dispatch_flatbuffers::dispatch(state, control, zero_copy), _ => panic!("bad op_id"), }; |