diff options
Diffstat (limited to 'components')
-rw-r--r-- | components/script/dom/globalscope.rs | 50 | ||||
-rw-r--r-- | components/script/timers.rs | 59 |
2 files changed, 53 insertions, 56 deletions
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 87e7a5ffc1c..d45556cad56 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -60,7 +60,7 @@ use script_traits::{ PortMessageTask, ScriptMsg, ScriptToConstellationChan, }; use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; -use timers::{BoxedTimerCallback, TimerEvent, TimerEventId, TimerEventRequest, TimerSource}; +use timers::{TimerEventId, TimerEventRequest, TimerSource}; use uuid::Uuid; #[cfg(feature = "webgpu")] use webgpu::{DeviceLostReason, WebGPUDevice}; @@ -386,13 +386,6 @@ struct BroadcastListener { context: Trusted<GlobalScope>, } -/// A wrapper between timer events coming in over IPC, and the event-loop. -#[derive(Clone)] -pub(crate) struct TimerListener { - task_source: TaskSource, - context: Trusted<GlobalScope>, -} - type FileListenerCallback = Box<dyn Fn(Rc<Promise>, Fallible<Vec<u8>>) + Send>; /// A wrapper for the handling of file data received by the ipc router @@ -525,37 +518,6 @@ impl BroadcastListener { } } -impl TimerListener { - /// Handle a timer-event coming from the [`timers::TimerScheduler`] - /// by queuing the appropriate task on the relevant event-loop. - fn handle(&self, event: TimerEvent) { - let context = self.context.clone(); - // Step 18, queue a task, - // https://html.spec.whatwg.org/multipage/#timer-initialisation-steps - let _ = self.task_source.queue( - task!(timer_event: move || { - let global = context.root(); - let TimerEvent(source, id) = event; - match source { - TimerSource::FromWorker => { - global.downcast::<WorkerGlobalScope>().expect("Window timer delivered to worker"); - }, - TimerSource::FromWindow(pipeline) => { - assert_eq!(pipeline, global.pipeline_id()); - global.downcast::<Window>().expect("Worker timer delivered to window"); - }, - }; - // Step 7, substeps run in a task. - global.fire_timer(id, CanGc::note()); - }) - ); - } - - pub fn into_callback(self) -> BoxedTimerCallback { - Box::new(move |timer_event| self.handle(timer_event)) - } -} - impl MessageListener { /// A new message came in, handle it via a task enqueued on the event-loop. /// A task is required, since we are using a trusted globalscope, @@ -825,15 +787,7 @@ impl GlobalScope { } fn timers(&self) -> &OneshotTimers { - self.timers.get_or_init(|| { - OneshotTimers::new( - self, - TimerListener { - context: Trusted::new(self), - task_source: self.task_manager().timer_task_source(), - }, - ) - }) + self.timers.get_or_init(|| OneshotTimers::new(self)) } /// <https://w3c.github.io/ServiceWorker/#get-the-service-worker-registration-object> diff --git a/components/script/timers.rs b/components/script/timers.rs index 75119ea1421..8eaf37b8c70 100644 --- a/components/script/timers.rs +++ b/components/script/timers.rs @@ -14,23 +14,27 @@ use js::jsapi::Heap; use js::jsval::{JSVal, UndefinedValue}; use js::rust::HandleValue; use servo_config::pref; -use timers::{TimerEventId, TimerEventRequest, TimerSource}; +use timers::{BoxedTimerCallback, TimerEvent, TimerEventId, TimerEventRequest, TimerSource}; use crate::dom::bindings::callback::ExceptionHandling::Report; use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::FunctionBinding::Function; +use crate::dom::bindings::inheritance::Castable; +use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::str::DOMString; use crate::dom::document::FakeRequestAnimationFrameCallback; use crate::dom::eventsource::EventSourceTimeoutCallback; -use crate::dom::globalscope::{GlobalScope, TimerListener}; +use crate::dom::globalscope::GlobalScope; use crate::dom::htmlmetaelement::RefreshRedirectDue; use crate::dom::testbinding::TestBindingCallback; +use crate::dom::types::{Window, WorkerGlobalScope}; use crate::dom::xmlhttprequest::XHRTimeoutCallback; use crate::script_module::ScriptFetchOptions; use crate::script_runtime::CanGc; use crate::script_thread::ScriptThread; +use crate::task_source::TaskSource; #[derive(Clone, Copy, Debug, Eq, Hash, JSTraceable, MallocSizeOf, Ord, PartialEq, PartialOrd)] pub struct OneshotTimerHandle(i32); @@ -38,9 +42,6 @@ pub struct OneshotTimerHandle(i32); #[derive(DenyPublicFields, JSTraceable, MallocSizeOf)] pub struct OneshotTimers { global_scope: DomRoot<GlobalScope>, - #[ignore_malloc_size_of = "Missing malloc_size_of for task types"] - #[no_trace] - timer_listener: TimerListener, js_timers: JsTimers, next_timer_handle: Cell<OneshotTimerHandle>, timers: DomRefCell<Vec<OneshotTimer>>, @@ -118,10 +119,9 @@ impl PartialEq for OneshotTimer { } impl OneshotTimers { - pub fn new(global_scope: &GlobalScope, timer_listener: TimerListener) -> OneshotTimers { + pub fn new(global_scope: &GlobalScope) -> OneshotTimers { OneshotTimers { global_scope: DomRoot::from_ref(global_scope), - timer_listener, js_timers: JsTimers::default(), next_timer_handle: Cell::new(OneshotTimerHandle(1)), timers: DomRefCell::new(Vec::new()), @@ -283,9 +283,15 @@ impl OneshotTimers { return; }; + let callback = TimerListener { + context: Trusted::new(&*self.global_scope), + task_source: self.global_scope.task_manager().timer_task_source(), + } + .into_callback(); + let expected_event_id = self.invalidate_expected_event_id(); let event_request = TimerEventRequest { - callback: self.timer_listener.clone().into_callback(), + callback, source: timer.source, id: expected_event_id, duration: timer.scheduled_for - Instant::now(), @@ -574,3 +580,40 @@ impl JsTimerTask { .collect() } } + +/// A wrapper between timer events coming in over IPC, and the event-loop. +#[derive(Clone)] +struct TimerListener { + task_source: TaskSource, + context: Trusted<GlobalScope>, +} + +impl TimerListener { + /// Handle a timer-event coming from the [`timers::TimerScheduler`] + /// by queuing the appropriate task on the relevant event-loop. + fn handle(&self, event: TimerEvent) { + let context = self.context.clone(); + // Step 18, queue a task, + // https://html.spec.whatwg.org/multipage/#timer-initialisation-steps + let _ = self.task_source.queue(task!(timer_event: move || { + let global = context.root(); + let TimerEvent(source, id) = event; + match source { + TimerSource::FromWorker => { + global.downcast::<WorkerGlobalScope>().expect("Window timer delivered to worker"); + }, + TimerSource::FromWindow(pipeline) => { + assert_eq!(pipeline, global.pipeline_id()); + global.downcast::<Window>().expect("Worker timer delivered to window"); + }, + }; + // Step 7, substeps run in a task. + global.fire_timer(id, CanGc::note()); + }) + ); + } + + fn into_callback(self) -> BoxedTimerCallback { + Box::new(move |timer_event| self.handle(timer_event)) + } +} |