summaryrefslogtreecommitdiff
path: root/src/handlers.rs
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2018-09-27 17:33:10 -0400
committerGitHub <noreply@github.com>2018-09-27 17:33:10 -0400
commitd38ccfc6dcb8643daa4f9e695d47a79cf068f90e (patch)
treed36ad2934e8550242d50e866f4ad2b6c303646b7 /src/handlers.rs
parentbf93ca54dd85686c7b93a6189913e48e10de8dcf (diff)
Support zero-copy data in libdeno.send(). (#838)
This is a large API refactor of deno.h which replaces deno_send() and deno_set_response() with deno_respond(). It also adds a req_id parameter to the deno_recv_cb. Make writeFile/writeFileSync use it.
Diffstat (limited to 'src/handlers.rs')
-rw-r--r--src/handlers.rs150
1 files changed, 124 insertions, 26 deletions
diff --git a/src/handlers.rs b/src/handlers.rs
index 43097918d..62bdabb61 100644
--- a/src/handlers.rs
+++ b/src/handlers.rs
@@ -33,15 +33,21 @@ type OpResult = DenoResult<Buf>;
// TODO Ideally we wouldn't have to box the Op being returned.
// The box is just to make it easier to get a prototype refactor working.
-type Handler = fn(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op>;
+type Handler =
+ fn(state: Arc<IsolateState>, base: &msg::Base, data: &'static mut [u8])
+ -> Box<Op>;
// Hopefully Rust optimizes this away.
fn empty_buf() -> Buf {
Box::new([])
}
-pub fn msg_from_js(state: Arc<IsolateState>, bytes: &[u8]) -> (bool, Box<Op>) {
- let base = msg::get_root_as_base(bytes);
+pub fn msg_from_js(
+ state: Arc<IsolateState>,
+ control: &[u8],
+ data: &'static mut [u8],
+) -> (bool, Box<Op>) {
+ let base = msg::get_root_as_base(control);
let is_sync = base.sync();
let msg_type = base.msg_type();
let cmd_id = base.cmd_id();
@@ -71,7 +77,7 @@ pub fn msg_from_js(state: Arc<IsolateState>, bytes: &[u8]) -> (bool, Box<Op>) {
)),
};
- let op: Box<Op> = handler(state.clone(), &base);
+ let op: Box<Op> = handler(state.clone(), &base, data);
let boxed_op = Box::new(
op.or_else(move |err: DenoError| -> DenoResult<Buf> {
debug!("op err {}", err);
@@ -130,12 +136,21 @@ fn not_implemented() -> DenoError {
))
}
-fn handle_exit(_config: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_exit(
+ _config: Arc<IsolateState>,
+ base: &msg::Base,
+ _data: &'static mut [u8],
+) -> Box<Op> {
let msg = base.msg_as_exit().unwrap();
std::process::exit(msg.code())
}
-fn handle_start(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_start(
+ state: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
let mut builder = FlatBufferBuilder::new();
let argv = state.argv.iter().map(|s| s.as_str()).collect::<Vec<_>>();
@@ -191,7 +206,12 @@ fn odd_future(err: DenoError) -> Box<Op> {
}
// https://github.com/denoland/isolate/blob/golang/os.go#L100-L154
-fn handle_code_fetch(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_code_fetch(
+ state: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
let msg = base.msg_as_code_fetch().unwrap();
let cmd_id = base.cmd_id();
let module_specifier = msg.module_specifier().unwrap();
@@ -228,7 +248,12 @@ fn handle_code_fetch(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
}
// https://github.com/denoland/isolate/blob/golang/os.go#L156-L169
-fn handle_code_cache(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_code_cache(
+ state: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
let msg = base.msg_as_code_cache().unwrap();
let filename = msg.filename().unwrap();
let source_code = msg.source_code().unwrap();
@@ -239,7 +264,12 @@ fn handle_code_cache(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
}()))
}
-fn handle_set_timeout(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_set_timeout(
+ state: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
let msg = base.msg_as_set_timeout().unwrap();
let val = msg.timeout() as isize;
state
@@ -248,7 +278,12 @@ fn handle_set_timeout(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
ok_future(empty_buf())
}
-fn handle_set_env(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_set_env(
+ state: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
let msg = base.msg_as_set_env().unwrap();
let key = msg.key().unwrap();
let value = msg.value().unwrap();
@@ -261,7 +296,12 @@ fn handle_set_env(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
ok_future(empty_buf())
}
-fn handle_env(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_env(
+ state: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
let cmd_id = base.cmd_id();
if !state.flags.allow_env {
@@ -302,7 +342,12 @@ fn handle_env(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
))
}
-fn handle_fetch_req(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_fetch_req(
+ state: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
let msg = base.msg_as_fetch_req().unwrap();
let cmd_id = base.cmd_id();
let id = msg.id();
@@ -436,7 +481,12 @@ macro_rules! blocking {
};
}
-fn handle_make_temp_dir(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_make_temp_dir(
+ state: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
let base = Box::new(*base);
let msg = base.msg_as_make_temp_dir().unwrap();
let cmd_id = base.cmd_id();
@@ -480,7 +530,12 @@ fn handle_make_temp_dir(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
})
}
-fn handle_mkdir(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_mkdir(
+ state: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
let msg = base.msg_as_mkdir().unwrap();
let mode = msg.mode();
let path = String::from(msg.path().unwrap());
@@ -496,7 +551,12 @@ fn handle_mkdir(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
})
}
-fn handle_remove(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_remove(
+ state: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
let msg = base.msg_as_remove().unwrap();
let path = PathBuf::from(msg.path().unwrap());
let recursive = msg.recursive();
@@ -520,7 +580,12 @@ fn handle_remove(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
}
// Prototype https://github.com/denoland/isolate/blob/golang/os.go#L171-L184
-fn handle_read_file(_config: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_read_file(
+ _config: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
let msg = base.msg_as_read_file().unwrap();
let cmd_id = base.cmd_id();
let filename = PathBuf::from(msg.filename().unwrap());
@@ -570,7 +635,12 @@ fn get_mode(_perm: fs::Permissions) -> u32 {
0
}
-fn handle_stat(_config: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_stat(
+ _config: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
let msg = base.msg_as_stat().unwrap();
let cmd_id = base.cmd_id();
let filename = PathBuf::from(msg.filename().unwrap());
@@ -612,7 +682,11 @@ fn handle_stat(_config: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
})
}
-fn handle_write_file(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_write_file(
+ state: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
let msg = base.msg_as_write_file().unwrap();
if !state.flags.allow_write {
@@ -620,12 +694,11 @@ fn handle_write_file(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
}
let filename = String::from(msg.filename().unwrap());
- let data = Vec::from(msg.data().unwrap());
let perm = msg.perm();
blocking!(base.sync(), || -> OpResult {
- debug!("handle_write_file {}", filename);
- deno_fs::write_file(Path::new(&filename), data.as_slice(), perm)?;
+ debug!("handle_write_file {} {}", filename, data.len());
+ deno_fs::write_file(Path::new(&filename), data, perm)?;
Ok(empty_buf())
})
}
@@ -636,7 +709,12 @@ fn remove_timer(state: Arc<IsolateState>, timer_id: u32) {
}
// Prototype: https://github.com/ry/isolate/blob/golang/timers.go#L25-L39
-fn handle_timer_start(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_timer_start(
+ state: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
debug!("handle_timer_start");
let msg = base.msg_as_timer_start().unwrap();
let cmd_id = base.cmd_id();
@@ -679,14 +757,24 @@ fn handle_timer_start(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
}
// Prototype: https://github.com/ry/isolate/blob/golang/timers.go#L40-L43
-fn handle_timer_clear(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_timer_clear(
+ state: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
let msg = base.msg_as_timer_clear().unwrap();
debug!("handle_timer_clear");
remove_timer(state, msg.id());
ok_future(empty_buf())
}
-fn handle_rename(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_rename(
+ state: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
if !state.flags.allow_write {
return odd_future(permission_denied());
}
@@ -700,7 +788,12 @@ fn handle_rename(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
})
}
-fn handle_symlink(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_symlink(
+ state: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
if !state.flags.allow_write {
return odd_future(permission_denied());
}
@@ -720,7 +813,12 @@ fn handle_symlink(state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
})
}
-fn handle_read_link(_state: Arc<IsolateState>, base: &msg::Base) -> Box<Op> {
+fn handle_read_link(
+ _state: Arc<IsolateState>,
+ base: &msg::Base,
+ data: &'static mut [u8],
+) -> Box<Op> {
+ assert_eq!(data.len(), 0);
let msg = base.msg_as_readlink().unwrap();
let cmd_id = base.cmd_id();
let name = PathBuf::from(msg.name().unwrap());