Skip to main content

v8/
microtask.rs

1// Copyright 2019-2021 the Deno authors. All rights reserved. MIT license.
2
3use crate::Function;
4use crate::Isolate;
5use crate::Local;
6use crate::MicrotasksPolicy;
7use crate::UniqueRef;
8use crate::isolate::RealIsolate;
9use crate::support::Opaque;
10use crate::support::int;
11
12unsafe extern "C" {
13  fn v8__MicrotaskQueue__New(
14    isolate: *mut RealIsolate,
15    policy: MicrotasksPolicy,
16  ) -> *mut MicrotaskQueue;
17  fn v8__MicrotaskQueue__DESTRUCT(queue: *mut MicrotaskQueue);
18  fn v8__MicrotaskQueue__PerformCheckpoint(
19    isolate: *mut RealIsolate,
20    queue: *const MicrotaskQueue,
21  );
22  fn v8__MicrotaskQueue__IsRunningMicrotasks(
23    queue: *const MicrotaskQueue,
24  ) -> bool;
25  fn v8__MicrotaskQueue__GetMicrotasksScopeDepth(
26    queue: *const MicrotaskQueue,
27  ) -> int;
28  fn v8__MicrotaskQueue__EnqueueMicrotask(
29    isolate: *mut RealIsolate,
30    queue: *const MicrotaskQueue,
31    microtask: *const Function,
32  );
33}
34
35/// Represents the microtask queue, where microtasks are stored and processed.
36/// https://html.spec.whatwg.org/multipage/webappapis.html#microtask-queue
37/// https://html.spec.whatwg.org/multipage/webappapis.html#enqueuejob(queuename,-job,-arguments)
38/// https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint
39///
40/// A MicrotaskQueue instance may be associated to multiple Contexts by passing
41/// it to Context::New(), and they can be detached by Context::DetachGlobal().
42/// The embedder must keep the MicrotaskQueue instance alive until all associated
43/// Contexts are gone or detached.
44///
45/// Use the same instance of MicrotaskQueue for all Contexts that may access each
46/// other synchronously. E.g. for Web embedding, use the same instance for all
47/// origins that share the same URL scheme and eTLD+1.
48#[repr(C)]
49#[derive(Debug)]
50pub struct MicrotaskQueue(Opaque);
51
52impl MicrotaskQueue {
53  pub fn new(
54    isolate: &mut Isolate,
55    policy: MicrotasksPolicy,
56  ) -> UniqueRef<Self> {
57    unsafe {
58      UniqueRef::from_raw(v8__MicrotaskQueue__New(
59        isolate.as_real_ptr(),
60        policy,
61      ))
62    }
63  }
64
65  pub fn enqueue_microtask(
66    &self,
67    isolate: &mut Isolate,
68    microtask: Local<Function>,
69  ) {
70    unsafe {
71      v8__MicrotaskQueue__EnqueueMicrotask(
72        isolate.as_real_ptr(),
73        self,
74        &*microtask,
75      )
76    }
77  }
78
79  /// Adds a callback to notify the embedder after microtasks were run. The
80  /// callback is triggered by explicit RunMicrotasks call or automatic
81  /// microtasks execution (see Isolate::SetMicrotasksPolicy).
82  ///
83  /// Callback will trigger even if microtasks were attempted to run,
84  /// but the microtasks queue was empty and no single microtask was actually
85  /// executed.
86  ///
87  /// Executing scripts inside the callback will not re-trigger microtasks and
88  /// the callback.
89  pub fn perform_checkpoint(&self, isolate: &mut Isolate) {
90    unsafe {
91      v8__MicrotaskQueue__PerformCheckpoint(isolate.as_real_ptr(), self);
92    }
93  }
94
95  /// Removes callback that was installed by AddMicrotasksCompletedCallback.
96  pub fn is_running_microtasks(&self) -> bool {
97    unsafe { v8__MicrotaskQueue__IsRunningMicrotasks(self) }
98  }
99
100  /// Returns the current depth of nested MicrotasksScope that has kRunMicrotasks.
101  pub fn get_microtasks_scope_depth(&self) -> i32 {
102    unsafe { v8__MicrotaskQueue__GetMicrotasksScopeDepth(self) }
103  }
104}
105
106impl Drop for MicrotaskQueue {
107  fn drop(&mut self) {
108    unsafe { v8__MicrotaskQueue__DESTRUCT(self) }
109  }
110}