mirror of
https://github.com/servo/servo.git
synced 2025-06-19 06:38:59 +01:00
Store microtask queues in their global (fixes #18467)
This commit is contained in:
parent
7481ce177f
commit
24cf15a014
7 changed files with 29 additions and 78 deletions
|
@ -247,7 +247,7 @@ impl DedicatedWorkerGlobalScope {
|
|||
global.handle_event(event);
|
||||
// Step 6
|
||||
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);
|
||||
}).expect("Thread spawning failed");
|
||||
|
|
|
@ -63,6 +63,9 @@ impl DissimilarOriginWindow {
|
|||
global_to_clone_from.resource_threads().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),
|
||||
location: Default::default(),
|
||||
|
|
|
@ -33,7 +33,7 @@ use js::jsapi::{JS_GetObjectRuntime, MutableHandleValue};
|
|||
use js::panic::maybe_resume_unwind;
|
||||
use js::rust::{CompileOptionsWrapper, Runtime, get_object_class};
|
||||
use libc;
|
||||
use microtask::Microtask;
|
||||
use microtask::{Microtask, MicrotaskQueue};
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use net_traits::{CoreResourceThread, ResourceThreads, IpcSend};
|
||||
use profile_traits::{mem, time};
|
||||
|
@ -46,6 +46,7 @@ use std::cell::Cell;
|
|||
use std::collections::HashMap;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::ffi::CString;
|
||||
use std::rc::Rc;
|
||||
use task_source::file_reading::FileReadingTaskSource;
|
||||
use task_source::networking::NetworkingTaskSource;
|
||||
use task_source::performance_timeline::PerformanceTimelineTaskSource;
|
||||
|
@ -99,6 +100,15 @@ pub struct GlobalScope {
|
|||
|
||||
/// The origin of the globalscope
|
||||
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 {
|
||||
|
@ -112,6 +122,7 @@ impl GlobalScope {
|
|||
resource_threads: ResourceThreads,
|
||||
timer_event_chan: IpcSender<TimerEvent>,
|
||||
origin: MutableOrigin,
|
||||
microtask_queue: Rc<MicrotaskQueue>,
|
||||
) -> Self {
|
||||
Self {
|
||||
eventtarget: EventTarget::new_inherited(),
|
||||
|
@ -129,6 +140,7 @@ impl GlobalScope {
|
|||
resource_threads,
|
||||
timers: OneshotTimers::new(timer_event_chan, scheduler_chan),
|
||||
origin,
|
||||
microtask_queue,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -479,30 +491,12 @@ impl GlobalScope {
|
|||
|
||||
/// Perform a microtask checkpoint.
|
||||
pub fn perform_a_microtask_checkpoint(&self) {
|
||||
if let Some(window) = self.downcast::<Window>() {
|
||||
return window.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!();
|
||||
self.microtask_queue.checkpoint(|_| Some(Root::from_ref(self)));
|
||||
}
|
||||
|
||||
/// Enqueue a microtask for subsequent execution.
|
||||
pub fn enqueue_microtask(&self, job: Microtask) {
|
||||
if let Some(window) = self.downcast::<Window>() {
|
||||
return window.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!();
|
||||
self.microtask_queue.enqueue(job);
|
||||
}
|
||||
|
||||
/// Create a new sender/receiver pair that can be used to implement an on-demand
|
||||
|
@ -518,6 +512,11 @@ impl GlobalScope {
|
|||
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
|
||||
/// in the thread queue for this global scope.
|
||||
pub fn process_event(&self, msg: CommonScriptMsg) {
|
||||
|
|
|
@ -219,7 +219,7 @@ impl ServiceWorkerGlobalScope {
|
|||
break;
|
||||
}
|
||||
// Step 6
|
||||
global.upcast::<WorkerGlobalScope>().perform_a_microtask_checkpoint();
|
||||
global.upcast::<GlobalScope>().perform_a_microtask_checkpoint();
|
||||
}
|
||||
}, reporter_name, scope.script_chan(), CommonScriptMsg::CollectReports);
|
||||
}).expect("Thread spawning failed");
|
||||
|
|
|
@ -59,7 +59,7 @@ use js::jsapi::{JS_GC, JS_GetRuntime};
|
|||
use js::jsval::UndefinedValue;
|
||||
use js::rust::Runtime;
|
||||
use layout_image::fetch_image_for_layout;
|
||||
use microtask::{Microtask, MicrotaskQueue};
|
||||
use microtask::MicrotaskQueue;
|
||||
use msg::constellation_msg::{FrameType, PipelineId};
|
||||
use net_traits::{ResourceThreads, ReferrerPolicy};
|
||||
use net_traits::image_cache::{ImageCache, ImageResponder, ImageResponse};
|
||||
|
@ -288,10 +288,6 @@ pub struct Window {
|
|||
test_worklet: MutNullableJS<Worklet>,
|
||||
/// https://drafts.css-houdini.org/css-paint-api-1/#paint-worklet
|
||||
paint_worklet: MutNullableJS<Worklet>,
|
||||
|
||||
/// https://html.spec.whatwg.org/multipage/#microtask-queue
|
||||
#[ignore_heap_size_of = "Rc<T> is hard"]
|
||||
microtask_queue: Rc<MicrotaskQueue>,
|
||||
}
|
||||
|
||||
impl Window {
|
||||
|
@ -1790,16 +1786,6 @@ impl Window {
|
|||
.send(msg)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn enqueue_microtask(&self, job: Microtask) {
|
||||
self.microtask_queue.enqueue(job);
|
||||
}
|
||||
|
||||
pub fn perform_a_microtask_checkpoint(&self) {
|
||||
self.microtask_queue.checkpoint(|_| {
|
||||
Some(Root::from_ref(self.upcast::<GlobalScope>()))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl Window {
|
||||
|
@ -1855,6 +1841,7 @@ impl Window {
|
|||
resource_threads,
|
||||
timer_event_chan,
|
||||
origin,
|
||||
microtask_queue,
|
||||
),
|
||||
script_chan,
|
||||
dom_manipulation_task_source,
|
||||
|
@ -1906,7 +1893,6 @@ impl Window {
|
|||
unminified_js_dir: Default::default(),
|
||||
test_worklet: Default::default(),
|
||||
paint_worklet: Default::default(),
|
||||
microtask_queue,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
|
|
|
@ -30,7 +30,6 @@ use js::jsapi::{HandleValue, JSAutoCompartment, JSContext, JSRuntime};
|
|||
use js::jsval::UndefinedValue;
|
||||
use js::panic::maybe_resume_unwind;
|
||||
use js::rust::Runtime;
|
||||
use microtask::{MicrotaskQueue, Microtask};
|
||||
use net_traits::{IpcSend, load_whole_resource};
|
||||
use net_traits::request::{CredentialsMode, Destination, RequestInit as NetRequestInit, Type as RequestType};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
|
||||
|
@ -91,10 +90,6 @@ pub struct WorkerGlobalScope {
|
|||
/// `IpcSender` doesn't exist
|
||||
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
|
||||
|
||||
/// https://html.spec.whatwg.org/multipage/#microtask-queue
|
||||
#[ignore_heap_size_of = "Rc<T> is hard"]
|
||||
microtask_queue: Rc<MicrotaskQueue>,
|
||||
|
||||
navigation_start_precise: f64,
|
||||
performance: MutNullableJS<Performance>,
|
||||
}
|
||||
|
@ -119,6 +114,7 @@ impl WorkerGlobalScope {
|
|||
init.resource_threads,
|
||||
timer_event_chan,
|
||||
MutableOrigin::new(init.origin),
|
||||
Default::default(),
|
||||
),
|
||||
worker_id: init.worker_id,
|
||||
worker_url,
|
||||
|
@ -128,7 +124,6 @@ impl WorkerGlobalScope {
|
|||
navigator: Default::default(),
|
||||
from_devtools_sender: init.from_devtools_sender,
|
||||
from_devtools_receiver,
|
||||
microtask_queue: Default::default(),
|
||||
navigation_start_precise: precise_time_ns() as f64,
|
||||
performance: Default::default(),
|
||||
}
|
||||
|
@ -171,18 +166,6 @@ impl WorkerGlobalScope {
|
|||
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 {
|
||||
|
|
|
@ -17,8 +17,6 @@ use ipc_channel::ipc::IpcSender;
|
|||
use js::jsapi::JSContext;
|
||||
use js::jsval::UndefinedValue;
|
||||
use js::rust::Runtime;
|
||||
use microtask::Microtask;
|
||||
use microtask::MicrotaskQueue;
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use net_traits::ResourceThreads;
|
||||
use net_traits::image_cache::ImageCache;
|
||||
|
@ -36,7 +34,6 @@ use script_traits::TimerSchedulerMsg;
|
|||
use servo_url::ImmutableOrigin;
|
||||
use servo_url::MutableOrigin;
|
||||
use servo_url::ServoUrl;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
|
@ -47,9 +44,6 @@ pub struct WorkletGlobalScope {
|
|||
globalscope: GlobalScope,
|
||||
/// The base URL for this worklet.
|
||||
base_url: ServoUrl,
|
||||
/// https://html.spec.whatwg.org/multipage/#microtask-queue
|
||||
#[ignore_heap_size_of = "Rc<T> is hard"]
|
||||
microtask_queue: Rc<MicrotaskQueue>,
|
||||
/// Sender back to the script thread
|
||||
#[ignore_heap_size_of = "channels are hard"]
|
||||
to_script_thread_sender: Sender<MainThreadScriptMsg>,
|
||||
|
@ -82,9 +76,9 @@ impl WorkletGlobalScope {
|
|||
init.resource_threads.clone(),
|
||||
timer_event_chan,
|
||||
MutableOrigin::new(ImmutableOrigin::new_opaque()),
|
||||
Default::default(),
|
||||
),
|
||||
base_url,
|
||||
microtask_queue: Default::default(),
|
||||
to_script_thread_sender: init.to_script_thread_sender.clone(),
|
||||
executor,
|
||||
}
|
||||
|
@ -133,20 +127,6 @@ impl WorkletGlobalScope {
|
|||
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
|
||||
pub fn perform_a_worklet_task(&self, task: WorkletTask) {
|
||||
match task {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue