diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2019-09-30 20:59:44 +0200 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2019-09-30 14:59:44 -0400 |
commit | ffbf0c20ccc4e70281958f18ed117f40bdd91397 (patch) | |
tree | 602fc442c91186e80a57eca85c5069f4a9be04d3 /core/isolate.rs | |
parent | ae26a9c7a22bf3311648a93a3171f087490c6e4d (diff) |
feat: op registration in core (#3002)
Diffstat (limited to 'core/isolate.rs')
-rw-r--r-- | core/isolate.rs | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/core/isolate.rs b/core/isolate.rs index bad79b579..6795f25f0 100644 --- a/core/isolate.rs +++ b/core/isolate.rs @@ -13,10 +13,10 @@ use crate::libdeno::deno_buf; use crate::libdeno::deno_dyn_import_id; use crate::libdeno::deno_mod; use crate::libdeno::deno_pinned_buf; -use crate::libdeno::OpId; use crate::libdeno::PinnedBuf; use crate::libdeno::Snapshot1; use crate::libdeno::Snapshot2; +use crate::ops::*; use crate::shared_queue::SharedQueue; use crate::shared_queue::RECOMMENDED_SIZE; use futures::stream::FuturesUnordered; @@ -34,24 +34,6 @@ use std::fmt; use std::ptr::null; use std::sync::{Arc, Mutex, Once}; -pub type Buf = Box<[u8]>; - -pub type OpAsyncFuture<E> = Box<dyn Future<Item = Buf, Error = E> + Send>; - -type PendingOpFuture = - Box<dyn Future<Item = (OpId, Buf), Error = CoreError> + Send>; - -pub enum Op<E> { - Sync(Buf), - Async(OpAsyncFuture<E>), -} - -pub type CoreError = (); - -pub type CoreOp = Op<CoreError>; - -pub type OpResult<E> = Result<Op<E>, E>; - /// Args: op_id, control_buf, zero_copy_buf type CoreDispatchFn = dyn Fn(OpId, &[u8], Option<PinnedBuf>) -> CoreOp; @@ -179,6 +161,7 @@ pub struct Isolate { pending_dyn_imports: FuturesUnordered<StreamFuture<DynImport>>, have_unpolled_ops: bool, startup_script: Option<OwnedScript>, + op_registry: OpRegistry, } unsafe impl Send for Isolate {} @@ -244,12 +227,17 @@ impl Isolate { have_unpolled_ops: false, pending_dyn_imports: FuturesUnordered::new(), startup_script, + op_registry: OpRegistry::new(), } } /// Defines the how Deno.core.dispatch() acts. /// Called whenever Deno.core.dispatch() is called in JavaScript. zero_copy_buf /// corresponds to the second argument of Deno.core.dispatch(). + /// + /// If this method is used then ops registered using `op_register` function are + /// ignored and all dispatching must be handled manually in provided callback. + // TODO: we want to deprecate and remove this API and move to `register_op` API pub fn set_dispatch<F>(&mut self, f: F) where F: Fn(OpId, &[u8], Option<PinnedBuf>) -> CoreOp + Send + Sync + 'static, @@ -257,6 +245,22 @@ impl Isolate { self.dispatch = Some(Arc::new(f)); } + /// New dispatch mechanism. Requires runtime to explicitly ask for op ids + /// before using any of the ops. + /// + /// Ops added using this method are only usable if `dispatch` is not set + /// (using `set_dispatch` method). + pub fn register_op<F>(&mut self, name: &str, op: F) -> OpId + where + F: Fn(&[u8], Option<PinnedBuf>) -> CoreOp + Send + Sync + 'static, + { + assert!( + self.dispatch.is_none(), + "set_dispatch should not be used in conjunction with register_op" + ); + self.op_registry.register(name, op) + } + pub fn set_dyn_import<F>(&mut self, f: F) where F: Fn(deno_dyn_import_id, &str, &str) -> DynImportStream @@ -329,9 +333,17 @@ impl Isolate { let isolate = unsafe { Isolate::from_raw_ptr(user_data) }; let op = if let Some(ref f) = isolate.dispatch { + assert!( + op_id != 0, + "op_id 0 is a special value that shouldn't be used with dispatch" + ); f(op_id, control_buf.as_ref(), PinnedBuf::new(zero_copy_buf)) } else { - panic!("isolate.dispatch not set") + isolate.op_registry.call( + op_id, + control_buf.as_ref(), + PinnedBuf::new(zero_copy_buf), + ) }; debug_assert_eq!(isolate.shared.size(), 0); |