mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
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:
commit
2c576e5613
8 changed files with 213 additions and 229 deletions
|
@ -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");
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue