Skip to content

Commit

Permalink
feat(core): Add support for async ops in realms (denoland#14734)
Browse files Browse the repository at this point in the history
Pull request denoland#14019 enabled initial support for realms, but it did not
include support for async ops anywhere other than the main realm. The
main issue was that the `js_recv_cb` callback, which resolves promises
corresponding to async ops, was only set for the main realm, so async
ops in other realms would never resolve. Furthermore, promise ID's are
specific to each realm, which meant that async ops from other realms
would result in a wrong promise from the main realm being resolved.

This change creates a `ContextState` struct, similar to
`JsRuntimeState` but stored in a slot of each `v8::Context`, which
contains a `js_recv_cb` callback for each realm. Combined with a new
list of known realms, which stores them as `v8::Weak<v8::Context>`,
and a change in the `#[op]` macro to pass the current context to
`queue_async_op`, this makes it possible to send the results of
promises for different realms to their realm, and prevent the ID's
from getting mixed up.

Additionally, since promise ID's are no longer unique to the isolate,
having a single set of unrefed ops doesn't work. This change therefore
also moves `unrefed_ops` from `JsRuntimeState` to `ContextState`, and
adds the lengths of the unrefed op sets for all known realms to get
the total number of unrefed ops to compare in the event loop.

Co-authored-by: Luis Malheiro <[email protected]>
  • Loading branch information
andreubotella and lmalheiro committed Aug 10, 2022
1 parent 5b2ae25 commit f16fe44
Show file tree
Hide file tree
Showing 3 changed files with 308 additions and 58 deletions.
9 changes: 5 additions & 4 deletions core/ops_builtin_v8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::ops_builtin::WasmStreamingResource;
use crate::resolve_url_or_path;
use crate::serde_v8::from_v8;
use crate::source_map::apply_source_map as apply_source_map_;
use crate::JsRealm;
use crate::JsRuntime;
use crate::OpDecl;
use crate::ZeroCopyBuf;
Expand Down Expand Up @@ -64,14 +65,14 @@ fn to_v8_fn(

#[op(v8)]
fn op_ref_op(scope: &mut v8::HandleScope, promise_id: i32) {
let state_rc = JsRuntime::state(scope);
state_rc.borrow_mut().unrefed_ops.remove(&promise_id);
let context_state = JsRealm::state_from_scope(scope);
context_state.borrow_mut().unrefed_ops.remove(&promise_id);
}

#[op(v8)]
fn op_unref_op(scope: &mut v8::HandleScope, promise_id: i32) {
let state_rc = JsRuntime::state(scope);
state_rc.borrow_mut().unrefed_ops.insert(promise_id);
let context_state = JsRealm::state_from_scope(scope);
context_state.borrow_mut().unrefed_ops.insert(promise_id);
}

#[op(v8)]
Expand Down

0 comments on commit f16fe44

Please sign in to comment.