Auto merge of #18480 - servo:rc-microtask-queue, r=jdm

Store microtask queues directly in GlobalScope

<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18480)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-09-13 09:18:41 -05:00 committed by GitHub
commit 2c576e5613
8 changed files with 213 additions and 229 deletions

View file

@ -247,7 +247,7 @@ impl DedicatedWorkerGlobalScope {
global.handle_event(event); global.handle_event(event);
// Step 6 // Step 6
let _ar = AutoWorkerReset::new(&global, worker.clone()); let _ar = AutoWorkerReset::new(&global, worker.clone());
global.upcast::<WorkerGlobalScope>().perform_a_microtask_checkpoint(); global.upcast::<GlobalScope>().perform_a_microtask_checkpoint();
} }
}, reporter_name, parent_sender, CommonScriptMsg::CollectReports); }, reporter_name, parent_sender, CommonScriptMsg::CollectReports);
}).expect("Thread spawning failed"); }).expect("Thread spawning failed");

View file

@ -45,29 +45,36 @@ pub struct DissimilarOriginWindow {
impl DissimilarOriginWindow { impl DissimilarOriginWindow {
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub fn new(global_to_clone_from: &GlobalScope, window_proxy: &WindowProxy) -> Root<DissimilarOriginWindow> { pub fn new(
global_to_clone_from: &GlobalScope,
window_proxy: &WindowProxy,
) -> Root<Self> {
let cx = global_to_clone_from.get_cx(); let cx = global_to_clone_from.get_cx();
// Any timer events fired on this window are ignored. // Any timer events fired on this window are ignored.
let (timer_event_chan, _) = ipc::channel().unwrap(); let (timer_event_chan, _) = ipc::channel().unwrap();
let win = box DissimilarOriginWindow { let win = box Self {
globalscope: GlobalScope::new_inherited(PipelineId::new(), globalscope: GlobalScope::new_inherited(
global_to_clone_from.devtools_chan().cloned(), PipelineId::new(),
global_to_clone_from.mem_profiler_chan().clone(), global_to_clone_from.devtools_chan().cloned(),
global_to_clone_from.time_profiler_chan().clone(), global_to_clone_from.mem_profiler_chan().clone(),
global_to_clone_from.script_to_constellation_chan().clone(), global_to_clone_from.time_profiler_chan().clone(),
global_to_clone_from.scheduler_chan().clone(), global_to_clone_from.script_to_constellation_chan().clone(),
global_to_clone_from.resource_threads().clone(), global_to_clone_from.scheduler_chan().clone(),
timer_event_chan, global_to_clone_from.resource_threads().clone(),
global_to_clone_from.origin().clone()), timer_event_chan,
global_to_clone_from.origin().clone(),
// FIXME(nox): The microtask queue is probably not important
// here, but this whole DOM interface is a hack anyway.
global_to_clone_from.microtask_queue().clone(),
),
window_proxy: JS::from_ref(window_proxy), window_proxy: JS::from_ref(window_proxy),
location: MutNullableJS::new(None), location: Default::default(),
}; };
unsafe { DissimilarOriginWindowBinding::Wrap(cx, win) } unsafe { DissimilarOriginWindowBinding::Wrap(cx, win) }
} }
#[allow(dead_code)]
pub fn origin(&self) -> &MutableOrigin { pub fn origin(&self) -> &MutableOrigin {
self.globalscope.origin() self.upcast::<GlobalScope>().origin()
} }
} }

View file

@ -33,7 +33,7 @@ use js::jsapi::{JS_GetObjectRuntime, MutableHandleValue};
use js::panic::maybe_resume_unwind; use js::panic::maybe_resume_unwind;
use js::rust::{CompileOptionsWrapper, Runtime, get_object_class}; use js::rust::{CompileOptionsWrapper, Runtime, get_object_class};
use libc; use libc;
use microtask::Microtask; use microtask::{Microtask, MicrotaskQueue};
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;
use net_traits::{CoreResourceThread, ResourceThreads, IpcSend}; use net_traits::{CoreResourceThread, ResourceThreads, IpcSend};
use profile_traits::{mem, time}; use profile_traits::{mem, time};
@ -46,6 +46,7 @@ use std::cell::Cell;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use std::ffi::CString; use std::ffi::CString;
use std::rc::Rc;
use task_source::file_reading::FileReadingTaskSource; use task_source::file_reading::FileReadingTaskSource;
use task_source::networking::NetworkingTaskSource; use task_source::networking::NetworkingTaskSource;
use task_source::performance_timeline::PerformanceTimelineTaskSource; use task_source::performance_timeline::PerformanceTimelineTaskSource;
@ -99,36 +100,47 @@ pub struct GlobalScope {
/// The origin of the globalscope /// The origin of the globalscope
origin: MutableOrigin, origin: MutableOrigin,
/// The microtask queue associated with this global.
///
/// It is refcounted because windows in the same script thread share the
/// same microtask queue.
///
/// https://html.spec.whatwg.org/multipage/#microtask-queue
#[ignore_heap_size_of = "Rc<T> is hard"]
microtask_queue: Rc<MicrotaskQueue>,
} }
impl GlobalScope { impl GlobalScope {
pub fn new_inherited( pub fn new_inherited(
pipeline_id: PipelineId, pipeline_id: PipelineId,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>, devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
mem_profiler_chan: mem::ProfilerChan, mem_profiler_chan: mem::ProfilerChan,
time_profiler_chan: time::ProfilerChan, time_profiler_chan: time::ProfilerChan,
script_to_constellation_chan: ScriptToConstellationChan, script_to_constellation_chan: ScriptToConstellationChan,
scheduler_chan: IpcSender<TimerSchedulerMsg>, scheduler_chan: IpcSender<TimerSchedulerMsg>,
resource_threads: ResourceThreads, resource_threads: ResourceThreads,
timer_event_chan: IpcSender<TimerEvent>, timer_event_chan: IpcSender<TimerEvent>,
origin: MutableOrigin) origin: MutableOrigin,
-> Self { microtask_queue: Rc<MicrotaskQueue>,
GlobalScope { ) -> Self {
Self {
eventtarget: EventTarget::new_inherited(), eventtarget: EventTarget::new_inherited(),
crypto: Default::default(), crypto: Default::default(),
next_worker_id: Cell::new(WorkerId(0)), next_worker_id: Cell::new(WorkerId(0)),
pipeline_id: pipeline_id, pipeline_id,
devtools_wants_updates: Default::default(), devtools_wants_updates: Default::default(),
console_timers: DOMRefCell::new(Default::default()), console_timers: DOMRefCell::new(Default::default()),
devtools_chan: devtools_chan, devtools_chan,
mem_profiler_chan: mem_profiler_chan, mem_profiler_chan,
time_profiler_chan: time_profiler_chan, time_profiler_chan,
script_to_constellation_chan: script_to_constellation_chan, script_to_constellation_chan,
scheduler_chan: scheduler_chan.clone(), scheduler_chan: scheduler_chan.clone(),
in_error_reporting_mode: Default::default(), in_error_reporting_mode: Default::default(),
resource_threads: resource_threads, resource_threads,
timers: OneshotTimers::new(timer_event_chan, scheduler_chan), timers: OneshotTimers::new(timer_event_chan, scheduler_chan),
origin: origin, origin,
microtask_queue,
} }
} }
@ -479,30 +491,12 @@ impl GlobalScope {
/// Perform a microtask checkpoint. /// Perform a microtask checkpoint.
pub fn perform_a_microtask_checkpoint(&self) { pub fn perform_a_microtask_checkpoint(&self) {
if self.is::<Window>() { self.microtask_queue.checkpoint(|_| Some(Root::from_ref(self)));
return ScriptThread::invoke_perform_a_microtask_checkpoint();
}
if let Some(worker) = self.downcast::<WorkerGlobalScope>() {
return worker.perform_a_microtask_checkpoint();
}
if let Some(worker) = self.downcast::<WorkletGlobalScope>() {
return worker.perform_a_microtask_checkpoint();
}
unreachable!();
} }
/// Enqueue a microtask for subsequent execution. /// Enqueue a microtask for subsequent execution.
pub fn enqueue_microtask(&self, job: Microtask) { pub fn enqueue_microtask(&self, job: Microtask) {
if self.is::<Window>() { self.microtask_queue.enqueue(job);
return ScriptThread::enqueue_microtask(job);
}
if let Some(worker) = self.downcast::<WorkerGlobalScope>() {
return worker.enqueue_microtask(job);
}
if let Some(worker) = self.downcast::<WorkletGlobalScope>() {
return worker.enqueue_microtask(job);
}
unreachable!();
} }
/// Create a new sender/receiver pair that can be used to implement an on-demand /// Create a new sender/receiver pair that can be used to implement an on-demand
@ -518,6 +512,11 @@ impl GlobalScope {
unreachable!(); unreachable!();
} }
/// Returns the microtask queue of this global.
pub fn microtask_queue(&self) -> &Rc<MicrotaskQueue> {
&self.microtask_queue
}
/// Process a single event as if it were the next event /// Process a single event as if it were the next event
/// in the thread queue for this global scope. /// in the thread queue for this global scope.
pub fn process_event(&self, msg: CommonScriptMsg) { pub fn process_event(&self, msg: CommonScriptMsg) {

View file

@ -219,7 +219,7 @@ impl ServiceWorkerGlobalScope {
break; break;
} }
// Step 6 // Step 6
global.upcast::<WorkerGlobalScope>().perform_a_microtask_checkpoint(); global.upcast::<GlobalScope>().perform_a_microtask_checkpoint();
} }
}, reporter_name, scope.script_chan(), CommonScriptMsg::CollectReports); }, reporter_name, scope.script_chan(), CommonScriptMsg::CollectReports);
}).expect("Thread spawning failed"); }).expect("Thread spawning failed");

View file

@ -59,6 +59,7 @@ use js::jsapi::{JS_GC, JS_GetRuntime};
use js::jsval::UndefinedValue; use js::jsval::UndefinedValue;
use js::rust::Runtime; use js::rust::Runtime;
use layout_image::fetch_image_for_layout; use layout_image::fetch_image_for_layout;
use microtask::MicrotaskQueue;
use msg::constellation_msg::{FrameType, PipelineId}; use msg::constellation_msg::{FrameType, PipelineId};
use net_traits::{ResourceThreads, ReferrerPolicy}; use net_traits::{ResourceThreads, ReferrerPolicy};
use net_traits::image_cache::{ImageCache, ImageResponder, ImageResponse}; use net_traits::image_cache::{ImageCache, ImageResponder, ImageResponse};
@ -1789,65 +1790,68 @@ impl Window {
impl Window { impl Window {
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub fn new(runtime: Rc<Runtime>, pub fn new(
script_chan: MainThreadScriptChan, runtime: Rc<Runtime>,
dom_task_source: DOMManipulationTaskSource, script_chan: MainThreadScriptChan,
user_task_source: UserInteractionTaskSource, dom_manipulation_task_source: DOMManipulationTaskSource,
network_task_source: NetworkingTaskSource, user_interaction_task_source: UserInteractionTaskSource,
history_task_source: HistoryTraversalTaskSource, networking_task_source: NetworkingTaskSource,
file_task_source: FileReadingTaskSource, history_traversal_task_source: HistoryTraversalTaskSource,
performance_timeline_task_source: PerformanceTimelineTaskSource, file_reading_task_source: FileReadingTaskSource,
image_cache_chan: Sender<ImageCacheMsg>, performance_timeline_task_source: PerformanceTimelineTaskSource,
image_cache: Arc<ImageCache>, image_cache_chan: Sender<ImageCacheMsg>,
resource_threads: ResourceThreads, image_cache: Arc<ImageCache>,
bluetooth_thread: IpcSender<BluetoothRequest>, resource_threads: ResourceThreads,
mem_profiler_chan: MemProfilerChan, bluetooth_thread: IpcSender<BluetoothRequest>,
time_profiler_chan: TimeProfilerChan, mem_profiler_chan: MemProfilerChan,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>, time_profiler_chan: TimeProfilerChan,
constellation_chan: ScriptToConstellationChan, devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
control_chan: IpcSender<ConstellationControlMsg>, constellation_chan: ScriptToConstellationChan,
scheduler_chan: IpcSender<TimerSchedulerMsg>, control_chan: IpcSender<ConstellationControlMsg>,
timer_event_chan: IpcSender<TimerEvent>, scheduler_chan: IpcSender<TimerSchedulerMsg>,
layout_chan: Sender<Msg>, timer_event_chan: IpcSender<TimerEvent>,
id: PipelineId, layout_chan: Sender<Msg>,
parent_info: Option<(PipelineId, FrameType)>, pipelineid: PipelineId,
window_size: Option<WindowSizeData>, parent_info: Option<(PipelineId, FrameType)>,
origin: MutableOrigin, window_size: Option<WindowSizeData>,
navigation_start: u64, origin: MutableOrigin,
navigation_start_precise: f64, navigation_start: u64,
webgl_chan: WebGLChan, navigation_start_precise: f64,
webvr_chan: Option<IpcSender<WebVRMsg>>) webgl_chan: WebGLChan,
-> Root<Window> { webvr_chan: Option<IpcSender<WebVRMsg>>,
microtask_queue: Rc<MicrotaskQueue>,
) -> Root<Self> {
let layout_rpc: Box<LayoutRPC + Send> = { let layout_rpc: Box<LayoutRPC + Send> = {
let (rpc_send, rpc_recv) = channel(); let (rpc_send, rpc_recv) = channel();
layout_chan.send(Msg::GetRPC(rpc_send)).unwrap(); layout_chan.send(Msg::GetRPC(rpc_send)).unwrap();
rpc_recv.recv().unwrap() rpc_recv.recv().unwrap()
}; };
let error_reporter = CSSErrorReporter { let error_reporter = CSSErrorReporter {
pipelineid: id, pipelineid,
script_chan: Arc::new(Mutex::new(control_chan)), script_chan: Arc::new(Mutex::new(control_chan)),
}; };
let win = box Window { let win = box Self {
globalscope: globalscope: GlobalScope::new_inherited(
GlobalScope::new_inherited( pipelineid,
id, devtools_chan,
devtools_chan, mem_profiler_chan,
mem_profiler_chan, time_profiler_chan,
time_profiler_chan, constellation_chan,
constellation_chan, scheduler_chan,
scheduler_chan, resource_threads,
resource_threads, timer_event_chan,
timer_event_chan, origin,
origin), microtask_queue,
script_chan: script_chan, ),
dom_manipulation_task_source: dom_task_source, script_chan,
user_interaction_task_source: user_task_source, dom_manipulation_task_source,
networking_task_source: network_task_source, user_interaction_task_source,
history_traversal_task_source: history_task_source, networking_task_source,
file_reading_task_source: file_task_source, history_traversal_task_source,
file_reading_task_source,
performance_timeline_task_source, performance_timeline_task_source,
image_cache_chan: image_cache_chan, image_cache_chan,
image_cache: image_cache.clone(), image_cache,
navigator: Default::default(), navigator: Default::default(),
history: Default::default(), history: Default::default(),
custom_element_registry: Default::default(), custom_element_registry: Default::default(),
@ -1860,34 +1864,33 @@ impl Window {
session_storage: Default::default(), session_storage: Default::default(),
local_storage: Default::default(), local_storage: Default::default(),
status: DOMRefCell::new(DOMString::new()), status: DOMRefCell::new(DOMString::new()),
parent_info: parent_info, parent_info,
dom_static: GlobalStaticData::new(), dom_static: GlobalStaticData::new(),
js_runtime: DOMRefCell::new(Some(runtime.clone())), js_runtime: DOMRefCell::new(Some(runtime.clone())),
bluetooth_thread: bluetooth_thread, bluetooth_thread,
bluetooth_extra_permission_data: BluetoothExtraPermissionData::new(), bluetooth_extra_permission_data: BluetoothExtraPermissionData::new(),
page_clip_rect: Cell::new(max_rect()), page_clip_rect: Cell::new(max_rect()),
resize_event: Cell::new(None), resize_event: Default::default(),
layout_chan: layout_chan, layout_chan,
layout_rpc: layout_rpc, layout_rpc,
window_size: Cell::new(window_size), window_size: Cell::new(window_size),
current_viewport: Cell::new(Rect::zero()), current_viewport: Cell::new(Rect::zero()),
suppress_reflow: Cell::new(true), suppress_reflow: Cell::new(true),
pending_reflow_count: Cell::new(0), pending_reflow_count: Default::default(),
current_state: Cell::new(WindowState::Alive), current_state: Cell::new(WindowState::Alive),
devtools_marker_sender: Default::default(),
devtools_marker_sender: DOMRefCell::new(None), devtools_markers: Default::default(),
devtools_markers: DOMRefCell::new(HashSet::new()), webdriver_script_chan: Default::default(),
webdriver_script_chan: DOMRefCell::new(None),
ignore_further_async_events: Default::default(), ignore_further_async_events: Default::default(),
error_reporter: error_reporter, error_reporter,
scroll_offsets: DOMRefCell::new(HashMap::new()), scroll_offsets: Default::default(),
media_query_lists: WeakMediaQueryListVec::new(), media_query_lists: WeakMediaQueryListVec::new(),
test_runner: Default::default(), test_runner: Default::default(),
webgl_chan: webgl_chan, webgl_chan,
webvr_chan: webvr_chan, webvr_chan,
permission_state_invocation_results: DOMRefCell::new(HashMap::new()), permission_state_invocation_results: Default::default(),
pending_layout_images: DOMRefCell::new(HashMap::new()), pending_layout_images: Default::default(),
unminified_js_dir: DOMRefCell::new(None), unminified_js_dir: Default::default(),
test_worklet: Default::default(), test_worklet: Default::default(),
paint_worklet: Default::default(), paint_worklet: Default::default(),
}; };

View file

@ -30,7 +30,6 @@ use js::jsapi::{HandleValue, JSAutoCompartment, JSContext, JSRuntime};
use js::jsval::UndefinedValue; use js::jsval::UndefinedValue;
use js::panic::maybe_resume_unwind; use js::panic::maybe_resume_unwind;
use js::rust::Runtime; use js::rust::Runtime;
use microtask::{MicrotaskQueue, Microtask};
use net_traits::{IpcSend, load_whole_resource}; use net_traits::{IpcSend, load_whole_resource};
use net_traits::request::{CredentialsMode, Destination, RequestInit as NetRequestInit, Type as RequestType}; use net_traits::request::{CredentialsMode, Destination, RequestInit as NetRequestInit, Type as RequestType};
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort}; use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
@ -91,41 +90,40 @@ pub struct WorkerGlobalScope {
/// `IpcSender` doesn't exist /// `IpcSender` doesn't exist
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>, from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
microtask_queue: MicrotaskQueue,
navigation_start_precise: f64, navigation_start_precise: f64,
performance: MutNullableJS<Performance>, performance: MutNullableJS<Performance>,
} }
impl WorkerGlobalScope { impl WorkerGlobalScope {
pub fn new_inherited(init: WorkerGlobalScopeInit, pub fn new_inherited(
worker_url: ServoUrl, init: WorkerGlobalScopeInit,
runtime: Runtime, worker_url: ServoUrl,
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>, runtime: Runtime,
timer_event_chan: IpcSender<TimerEvent>, from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
closing: Option<Arc<AtomicBool>>) timer_event_chan: IpcSender<TimerEvent>,
-> WorkerGlobalScope { closing: Option<Arc<AtomicBool>>,
WorkerGlobalScope { ) -> Self {
globalscope: Self {
GlobalScope::new_inherited( globalscope: GlobalScope::new_inherited(
init.pipeline_id, init.pipeline_id,
init.to_devtools_sender, init.to_devtools_sender,
init.mem_profiler_chan, init.mem_profiler_chan,
init.time_profiler_chan, init.time_profiler_chan,
init.script_to_constellation_chan, init.script_to_constellation_chan,
init.scheduler_chan, init.scheduler_chan,
init.resource_threads, init.resource_threads,
timer_event_chan, timer_event_chan,
MutableOrigin::new(init.origin)), MutableOrigin::new(init.origin),
Default::default(),
),
worker_id: init.worker_id, worker_id: init.worker_id,
worker_url: worker_url, worker_url,
closing: closing, closing,
runtime: runtime, runtime,
location: Default::default(), location: Default::default(),
navigator: Default::default(), navigator: Default::default(),
from_devtools_sender: init.from_devtools_sender, from_devtools_sender: init.from_devtools_sender,
from_devtools_receiver: from_devtools_receiver, from_devtools_receiver,
microtask_queue: MicrotaskQueue::default(),
navigation_start_precise: precise_time_ns() as f64, navigation_start_precise: precise_time_ns() as f64,
performance: Default::default(), performance: Default::default(),
} }
@ -168,18 +166,6 @@ impl WorkerGlobalScope {
cancelled: self.closing.clone(), cancelled: self.closing.clone(),
} }
} }
pub fn enqueue_microtask(&self, job: Microtask) {
self.microtask_queue.enqueue(job);
}
pub fn perform_a_microtask_checkpoint(&self) {
self.microtask_queue.checkpoint(|id| {
let global = self.upcast::<GlobalScope>();
assert_eq!(global.pipeline_id(), id);
Some(Root::from_ref(global))
});
}
} }
impl WorkerGlobalScopeMethods for WorkerGlobalScope { impl WorkerGlobalScopeMethods for WorkerGlobalScope {

View file

@ -17,8 +17,6 @@ use ipc_channel::ipc::IpcSender;
use js::jsapi::JSContext; use js::jsapi::JSContext;
use js::jsval::UndefinedValue; use js::jsval::UndefinedValue;
use js::rust::Runtime; use js::rust::Runtime;
use microtask::Microtask;
use microtask::MicrotaskQueue;
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;
use net_traits::ResourceThreads; use net_traits::ResourceThreads;
use net_traits::image_cache::ImageCache; use net_traits::image_cache::ImageCache;
@ -46,8 +44,6 @@ pub struct WorkletGlobalScope {
globalscope: GlobalScope, globalscope: GlobalScope,
/// The base URL for this worklet. /// The base URL for this worklet.
base_url: ServoUrl, base_url: ServoUrl,
/// The microtask queue for this worklet
microtask_queue: MicrotaskQueue,
/// Sender back to the script thread /// Sender back to the script thread
#[ignore_heap_size_of = "channels are hard"] #[ignore_heap_size_of = "channels are hard"]
to_script_thread_sender: Sender<MainThreadScriptMsg>, to_script_thread_sender: Sender<MainThreadScriptMsg>,
@ -57,31 +53,34 @@ pub struct WorkletGlobalScope {
impl WorkletGlobalScope { impl WorkletGlobalScope {
/// Create a new stack-allocated `WorkletGlobalScope`. /// Create a new stack-allocated `WorkletGlobalScope`.
pub fn new_inherited(pipeline_id: PipelineId, pub fn new_inherited(
base_url: ServoUrl, pipeline_id: PipelineId,
executor: WorkletExecutor, base_url: ServoUrl,
init: &WorkletGlobalScopeInit) executor: WorkletExecutor,
-> WorkletGlobalScope { init: &WorkletGlobalScopeInit,
) -> Self {
// Any timer events fired on this global are ignored. // Any timer events fired on this global are ignored.
let (timer_event_chan, _) = ipc::channel().unwrap(); let (timer_event_chan, _) = ipc::channel().unwrap();
let script_to_constellation_chan = ScriptToConstellationChan { let script_to_constellation_chan = ScriptToConstellationChan {
sender: init.to_constellation_sender.clone(), sender: init.to_constellation_sender.clone(),
pipeline_id: pipeline_id, pipeline_id,
}; };
WorkletGlobalScope { Self {
globalscope: GlobalScope::new_inherited(pipeline_id, globalscope: GlobalScope::new_inherited(
init.devtools_chan.clone(), pipeline_id,
init.mem_profiler_chan.clone(), init.devtools_chan.clone(),
init.time_profiler_chan.clone(), init.mem_profiler_chan.clone(),
script_to_constellation_chan, init.time_profiler_chan.clone(),
init.scheduler_chan.clone(), script_to_constellation_chan,
init.resource_threads.clone(), init.scheduler_chan.clone(),
timer_event_chan, init.resource_threads.clone(),
MutableOrigin::new(ImmutableOrigin::new_opaque())), timer_event_chan,
base_url: base_url, MutableOrigin::new(ImmutableOrigin::new_opaque()),
microtask_queue: MicrotaskQueue::default(), Default::default(),
),
base_url,
to_script_thread_sender: init.to_script_thread_sender.clone(), to_script_thread_sender: init.to_script_thread_sender.clone(),
executor: executor, executor,
} }
} }
@ -128,20 +127,6 @@ impl WorkletGlobalScope {
self.executor.clone() self.executor.clone()
} }
/// Queue up a microtask to be executed in this global.
pub fn enqueue_microtask(&self, job: Microtask) {
self.microtask_queue.enqueue(job);
}
/// Perform any queued microtasks.
pub fn perform_a_microtask_checkpoint(&self) {
self.microtask_queue.checkpoint(|id| {
let global = self.upcast::<GlobalScope>();
assert_eq!(global.pipeline_id(), id);
Some(Root::from_ref(global))
});
}
/// Perform a worklet task /// Perform a worklet task
pub fn perform_a_worklet_task(&self, task: WorkletTask) { pub fn perform_a_worklet_task(&self, task: WorkletTask) {
match task { match task {

View file

@ -515,7 +515,8 @@ pub struct ScriptThread {
content_process_shutdown_chan: IpcSender<()>, content_process_shutdown_chan: IpcSender<()>,
microtask_queue: MicrotaskQueue, /// https://html.spec.whatwg.org/multipage/#microtask-queue
microtask_queue: Rc<MicrotaskQueue>,
/// Microtask Queue for adding support for mutation observer microtasks /// Microtask Queue for adding support for mutation observer microtasks
mutation_observer_compound_microtask_queued: Cell<bool>, mutation_observer_compound_microtask_queued: Cell<bool>,
@ -843,7 +844,7 @@ impl ScriptThread {
// Ask the router to proxy IPC messages from the control port to us. // Ask the router to proxy IPC messages from the control port to us.
let control_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(state.control_port); let control_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(state.control_port);
let boxed_script_sender = MainThreadScriptChan(chan.clone()).clone(); let boxed_script_sender = box MainThreadScriptChan(chan.clone());
let (image_cache_channel, image_cache_port) = channel(); let (image_cache_channel, image_cache_port) = channel();
@ -892,7 +893,7 @@ impl ScriptThread {
content_process_shutdown_chan: state.content_process_shutdown_chan, content_process_shutdown_chan: state.content_process_shutdown_chan,
microtask_queue: MicrotaskQueue::default(), microtask_queue: Default::default(),
mutation_observer_compound_microtask_queued: Default::default(), mutation_observer_compound_microtask_queued: Default::default(),
@ -2038,34 +2039,37 @@ impl ScriptThread {
}; };
// Create the window and document objects. // Create the window and document objects.
let window = Window::new(self.js_runtime.clone(), let window = Window::new(
MainThreadScriptChan(sender.clone()), self.js_runtime.clone(),
DOMManipulationTaskSource(dom_sender.clone()), MainThreadScriptChan(sender.clone()),
UserInteractionTaskSource(user_sender.clone()), DOMManipulationTaskSource(dom_sender.clone()),
self.networking_task_source.clone(), UserInteractionTaskSource(user_sender.clone()),
HistoryTraversalTaskSource(history_sender.clone()), self.networking_task_source.clone(),
self.file_reading_task_source.clone(), HistoryTraversalTaskSource(history_sender.clone()),
self.performance_timeline_task_source.clone(), self.file_reading_task_source.clone(),
self.image_cache_channel.clone(), self.performance_timeline_task_source.clone(),
self.image_cache.clone(), self.image_cache_channel.clone(),
self.resource_threads.clone(), self.image_cache.clone(),
self.bluetooth_thread.clone(), self.resource_threads.clone(),
self.mem_profiler_chan.clone(), self.bluetooth_thread.clone(),
self.time_profiler_chan.clone(), self.mem_profiler_chan.clone(),
self.devtools_chan.clone(), self.time_profiler_chan.clone(),
script_to_constellation_chan, self.devtools_chan.clone(),
self.control_chan.clone(), script_to_constellation_chan,
self.scheduler_chan.clone(), self.control_chan.clone(),
ipc_timer_event_chan, self.scheduler_chan.clone(),
incomplete.layout_chan, ipc_timer_event_chan,
incomplete.pipeline_id, incomplete.layout_chan,
incomplete.parent_info, incomplete.pipeline_id,
incomplete.window_size, incomplete.parent_info,
origin, incomplete.window_size,
incomplete.navigation_start, origin,
incomplete.navigation_start_precise, incomplete.navigation_start,
self.webgl_chan.channel(), incomplete.navigation_start_precise,
self.webvr_chan.clone()); self.webgl_chan.channel(),
self.webvr_chan.clone(),
self.microtask_queue.clone(),
);
// Initialize the browsing context for the window. // Initialize the browsing context for the window.
let window_proxy = self.local_window_proxy(&window, let window_proxy = self.local_window_proxy(&window,