mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
script: Move TimerListener
creation to OneShotTimers
(#34825)
Before each `OneShotTimers` would have a `TimerListener` for its lifetime, holding the timer `TaskSource`. The issue with this is that the `TaskSource` for dedicated workers keeps the main thread object alive, so as long as the `OneShotTimers` alive (until the worker thread exists), the main thread object would never be garbage collected. This change makes the creation of the listener on-demand, avoiding the long-lived handle to the main thread object and slightly simplifying `OneShotTimers` at the expense of some more operations when scheduling a timer. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
b2eda71952
commit
5b6c75e358
2 changed files with 53 additions and 56 deletions
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue