diff options
author | Martin Robinson <mrobinson@igalia.com> | 2025-01-01 14:50:52 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-01 13:50:52 +0000 |
commit | 77cfca65c441ff1f8b54a507c9802e7ae6893e62 (patch) | |
tree | a7d141eb43f22a94ba6f4a548e0346e9358d49c5 /components/script/dom | |
parent | deb819f23368ed43b9312a439e48f9d5f961930c (diff) | |
download | servo-77cfca65c441ff1f8b54a507c9802e7ae6893e62.tar.gz servo-77cfca65c441ff1f8b54a507c9802e7ae6893e62.zip |
script: Eliminate code duplication in the task queue (#34798)
Instead of creating a type for each `TaskSource` variety have each `TaskSource`
hold the same kind of sender (this was inconsistent before, but each
sender was effectively the same trait object), a pipeline, and a
`TaskSourceName`. This elminates the need to reimplement the same
queuing code for every task source.
In addition, have workers hold their own `TaskManager`. This allows just
exposing the manager on the `GlobalScope`. Currently the `TaskCanceller`
is different, but this will also be eliminated in a followup change.
This is a the first step toward having a shared set of `Sender`s on
`GlobalScope`.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Diffstat (limited to 'components/script/dom')
39 files changed, 157 insertions, 258 deletions
diff --git a/components/script/dom/abstractworkerglobalscope.rs b/components/script/dom/abstractworkerglobalscope.rs index 0603a888436..966dacaffd1 100644 --- a/components/script/dom/abstractworkerglobalscope.rs +++ b/components/script/dom/abstractworkerglobalscope.rs @@ -35,7 +35,7 @@ impl ScriptChan for SendableWorkerScriptChan { self.sender.send(msg).map_err(|_| ()) } - fn as_boxed(&self) -> Box<dyn ScriptChan + Send> { + fn as_boxed(&self) -> Box<dyn ScriptChan> { Box::new(SendableWorkerScriptChan { sender: self.sender.clone(), worker: self.worker.clone(), @@ -62,7 +62,7 @@ impl ScriptChan for WorkerThreadWorkerChan { self.sender.send(msg).map_err(|_| ()) } - fn as_boxed(&self) -> Box<dyn ScriptChan + Send> { + fn as_boxed(&self) -> Box<dyn ScriptChan> { Box::new(WorkerThreadWorkerChan { sender: self.sender.clone(), worker: self.worker.clone(), diff --git a/components/script/dom/analysernode.rs b/components/script/dom/analysernode.rs index 47d8f255088..263cf7737d4 100644 --- a/components/script/dom/analysernode.rs +++ b/components/script/dom/analysernode.rs @@ -27,7 +27,6 @@ use crate::dom::bindings::reflector::reflect_dom_object_with_proto; use crate::dom::bindings::root::DomRoot; use crate::dom::window::Window; use crate::script_runtime::CanGc; -use crate::task_source::TaskSource; #[dom_struct] pub struct AnalyserNode { diff --git a/components/script/dom/audiocontext.rs b/components/script/dom/audiocontext.rs index 9a260617c58..544b8bb474a 100644 --- a/components/script/dom/audiocontext.rs +++ b/components/script/dom/audiocontext.rs @@ -35,7 +35,6 @@ use crate::dom::promise::Promise; use crate::dom::window::Window; use crate::realms::InRealm; use crate::script_runtime::CanGc; -use crate::task_source::TaskSource; #[dom_struct] pub struct AudioContext { diff --git a/components/script/dom/audioscheduledsourcenode.rs b/components/script/dom/audioscheduledsourcenode.rs index c8a970f390e..26a5002ce47 100644 --- a/components/script/dom/audioscheduledsourcenode.rs +++ b/components/script/dom/audioscheduledsourcenode.rs @@ -17,7 +17,6 @@ use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::num::Finite; use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::reflector::DomObject; -use crate::task_source::TaskSource; #[dom_struct] pub struct AudioScheduledSourceNode { diff --git a/components/script/dom/audiotracklist.rs b/components/script/dom/audiotracklist.rs index 889eb43147f..19dba0fee3c 100644 --- a/components/script/dom/audiotracklist.rs +++ b/components/script/dom/audiotracklist.rs @@ -16,7 +16,6 @@ use crate::dom::eventtarget::EventTarget; use crate::dom::htmlmediaelement::HTMLMediaElement; use crate::dom::window::Window; use crate::script_runtime::CanGc; -use crate::task_source::TaskSource; #[dom_struct] pub struct AudioTrackList { diff --git a/components/script/dom/baseaudiocontext.rs b/components/script/dom/baseaudiocontext.rs index a93c3d6dd3e..1da48d4b1c8 100644 --- a/components/script/dom/baseaudiocontext.rs +++ b/components/script/dom/baseaudiocontext.rs @@ -68,7 +68,6 @@ use crate::dom::stereopannernode::StereoPannerNode; use crate::dom::window::Window; use crate::realms::InRealm; use crate::script_runtime::CanGc; -use crate::task_source::TaskSource; #[allow(dead_code)] pub enum BaseAudioContextOptions { diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs index 116c2762e81..a76b7d72065 100644 --- a/components/script/dom/bluetooth.rs +++ b/components/script/dom/bluetooth.rs @@ -244,7 +244,7 @@ pub fn response_async<T: AsyncBluetoothListener + DomObject + 'static>( receiver: &T, ) -> IpcSender<BluetoothResponseResult> { let (action_sender, action_receiver) = ipc::channel().unwrap(); - let task_source = receiver.global().networking_task_source(); + let task_source = receiver.global().task_manager().networking_task_source(); let context = Arc::new(Mutex::new(BluetoothContext { promise: Some(TrustedPromise::new(promise.clone())), receiver: Trusted::new(receiver), diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index a6d65284cb7..6cdae855dba 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -60,8 +60,7 @@ use crate::script_runtime::{ ThreadSafeJSContext, }; use crate::task_queue::{QueuedTask, QueuedTaskConversion, TaskQueue}; -use crate::task_source::networking::NetworkingTaskSource; -use crate::task_source::TaskSourceName; +use crate::task_source::{TaskSource, TaskSourceName}; /// Set the `worker` field of a related DedicatedWorkerGlobalScope object to a particular /// value for the duration of this object's lifetime. This ensures that the related Worker @@ -192,7 +191,7 @@ pub struct DedicatedWorkerGlobalScope { worker: DomRefCell<Option<TrustedWorkerAddress>>, #[ignore_malloc_size_of = "Can't measure trait objects"] /// Sender to the parent thread. - parent_sender: Box<dyn ScriptChan + Send>, + parent_sender: Box<dyn ScriptChan>, #[ignore_malloc_size_of = "Arc"] #[no_trace] image_cache: Arc<dyn ImageCache>, @@ -381,13 +380,14 @@ impl DedicatedWorkerGlobalScope { .origin(origin); let runtime = unsafe { - let task_source = NetworkingTaskSource( - Box::new(WorkerThreadWorkerChan { + let task_source = TaskSource { + sender: Box::new(WorkerThreadWorkerChan { sender: own_sender.clone(), worker: worker.clone(), }), pipeline_id, - ); + name: TaskSourceName::Networking, + }; Runtime::new_with_parent(Some(parent), Some(task_source)) }; diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 60997d39277..229d0b11e3f 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -192,7 +192,7 @@ use crate::script_runtime::{CanGc, CommonScriptMsg, ScriptThreadEventCategory}; use crate::script_thread::{with_script_thread, ScriptThread}; use crate::stylesheet_set::StylesheetSetRef; use crate::task::TaskBox; -use crate::task_source::{TaskSource, TaskSourceName}; +use crate::task_source::TaskSourceName; use crate::timers::OneshotTimerCallback; /// The number of times we are allowed to see spurious `requestAnimationFrame()` calls before diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs index 504968931db..a64c5be8088 100644 --- a/components/script/dom/eventsource.rs +++ b/components/script/dom/eventsource.rs @@ -45,7 +45,7 @@ use crate::fetch::{create_a_potential_cors_request, FetchCanceller}; use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener}; use crate::realms::enter_realm; use crate::script_runtime::CanGc; -use crate::task_source::{TaskSource, TaskSourceName}; +use crate::task_source::TaskSourceName; use crate::timers::OneshotTimerCallback; const DEFAULT_RECONNECTION_TIME: Duration = Duration::from_millis(5000); @@ -113,7 +113,7 @@ impl EventSourceContext { let global = event_source.global(); let event_source = self.event_source.clone(); // FIXME(nox): Why are errors silenced here? - let _ = global.remote_event_task_source().queue( + let _ = global.task_manager().remote_event_task_source().queue( task!(announce_the_event_source_connection: move || { let event_source = event_source.root(); if event_source.ready_state.get() != ReadyState::Closed { @@ -146,7 +146,7 @@ impl EventSourceContext { let action_sender = self.action_sender.clone(); let global = event_source.global(); // FIXME(nox): Why are errors silenced here? - let _ = global.remote_event_task_source().queue( + let _ = global.task_manager().remote_event_task_source().queue( task!(reestablish_the_event_source_onnection: move || { let event_source = trusted_event_source.root(); @@ -259,7 +259,7 @@ impl EventSourceContext { let event_source = self.event_source.clone(); let event = Trusted::new(&*event); // FIXME(nox): Why are errors silenced here? - let _ = global.remote_event_task_source().queue( + let _ = global.task_manager().remote_event_task_source().queue( task!(dispatch_the_event_source_event: move || { let event_source = event_source.root(); if event_source.ready_state.get() != ReadyState::Closed { @@ -500,7 +500,7 @@ impl EventSource { let global = self.global(); let event_source = Trusted::new(self); // FIXME(nox): Why are errors silenced here? - let _ = global.remote_event_task_source().queue( + let _ = global.task_manager().remote_event_task_source().queue( task!(fail_the_event_source_connection: move || { let event_source = event_source.root(); if event_source.ready_state.get() != ReadyState::Closed { @@ -605,7 +605,7 @@ impl EventSourceMethods<crate::DomTypeHolder> for EventSource { }; let listener = NetworkListener { context: Arc::new(Mutex::new(context)), - task_source: global.networking_task_source(), + task_source: global.task_manager().networking_task_source(), canceller: Some(global.task_canceller(TaskSourceName::Networking)), }; ROUTER.add_typed_route( diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs index e8e697eec90..ad21a11f639 100644 --- a/components/script/dom/filereader.rs +++ b/components/script/dom/filereader.rs @@ -36,9 +36,41 @@ use crate::dom::globalscope::GlobalScope; use crate::dom::progressevent::ProgressEvent; use crate::realms::enter_realm; use crate::script_runtime::{CanGc, JSContext}; -use crate::task_source::file_reading::FileReadingTask; -use crate::task_source::{TaskSource, TaskSourceName}; +use crate::task::TaskOnce; +use crate::task_source::TaskSourceName; + +#[allow(dead_code)] +pub enum FileReadingTask { + ProcessRead(TrustedFileReader, GenerationId), + ProcessReadData(TrustedFileReader, GenerationId), + ProcessReadError(TrustedFileReader, GenerationId, DOMErrorName), + ProcessReadEOF(TrustedFileReader, GenerationId, ReadMetaData, Vec<u8>), +} + +impl TaskOnce for FileReadingTask { + fn run_once(self) { + self.handle_task(CanGc::note()); + } +} + +impl FileReadingTask { + pub fn handle_task(self, can_gc: CanGc) { + use self::FileReadingTask::*; + match self { + ProcessRead(reader, gen_id) => FileReader::process_read(reader, gen_id, can_gc), + ProcessReadData(reader, gen_id) => { + FileReader::process_read_data(reader, gen_id, can_gc) + }, + ProcessReadError(reader, gen_id, error) => { + FileReader::process_read_error(reader, gen_id, error, can_gc) + }, + ProcessReadEOF(reader, gen_id, metadata, blob_contents) => { + FileReader::process_read_eof(reader, gen_id, metadata, blob_contents, can_gc) + }, + } + } +} #[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)] pub enum FileReaderFunction { Text, @@ -472,7 +504,7 @@ impl FileReader { let filereader = Trusted::new(self); let global = self.global(); let canceller = global.task_canceller(TaskSourceName::FileReading); - let task_source = global.file_reading_task_source(); + let task_source = global.task_manager().file_reading_task_source(); // Queue tasks as appropriate. let task = FileReadingTask::ProcessRead(filereader.clone(), gen_id); diff --git a/components/script/dom/gamepadhapticactuator.rs b/components/script/dom/gamepadhapticactuator.rs index edffeddd901..6892092a9a5 100644 --- a/components/script/dom/gamepadhapticactuator.rs +++ b/components/script/dom/gamepadhapticactuator.rs @@ -28,12 +28,11 @@ use crate::dom::promise::Promise; use crate::realms::InRealm; use crate::script_runtime::{CanGc, JSContext}; use crate::task::TaskCanceller; -use crate::task_source::gamepad::GamepadTaskSource; use crate::task_source::{TaskSource, TaskSourceName}; struct HapticEffectListener { canceller: TaskCanceller, - task_source: GamepadTaskSource, + task_source: TaskSource, context: Trusted<GamepadHapticActuator>, } @@ -199,7 +198,7 @@ impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuato if let Some(promise) = self.playing_effect_promise.borrow_mut().take() { let trusted_promise = TrustedPromise::new(promise); - let _ = self.global().gamepad_task_source().queue( + let _ = self.global().task_manager().gamepad_task_source().queue( task!(preempt_promise: move || { let promise = trusted_promise.root(); let message = DOMString::from("preempted"); @@ -221,7 +220,7 @@ impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuato let (effect_complete_sender, effect_complete_receiver) = ipc::channel().expect("ipc channel failure"); let (task_source, canceller) = ( - self.global().gamepad_task_source(), + self.global().task_manager().gamepad_task_source(), self.global().task_canceller(TaskSourceName::Gamepad), ); let listener = HapticEffectListener { @@ -272,7 +271,7 @@ impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuato if let Some(promise) = self.playing_effect_promise.borrow_mut().take() { let trusted_promise = TrustedPromise::new(promise); - let _ = self.global().gamepad_task_source().queue( + let _ = self.global().task_manager().gamepad_task_source().queue( task!(preempt_promise: move || { let promise = trusted_promise.root(); let message = DOMString::from("preempted"); @@ -290,7 +289,7 @@ impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuato let (effect_stop_sender, effect_stop_receiver) = ipc::channel().expect("ipc channel failure"); let (task_source, canceller) = ( - self.global().gamepad_task_source(), + self.global().task_manager().gamepad_task_source(), self.global().task_canceller(TaskSourceName::Gamepad), ); let listener = HapticEffectListener { @@ -342,7 +341,7 @@ impl GamepadHapticActuator { let trusted_promise = TrustedPromise::new(promise); let sequence_id = self.sequence_id.get(); let reset_sequence_id = self.reset_sequence_id.get(); - let _ = self.global().gamepad_task_source().queue( + let _ = self.global().task_manager().gamepad_task_source().queue( task!(complete_promise: move || { if sequence_id != reset_sequence_id { warn!("Mismatched sequence/reset sequence ids: {} != {}", sequence_id, reset_sequence_id); @@ -364,7 +363,7 @@ impl GamepadHapticActuator { } let this = Trusted::new(self); - let _ = self.global().gamepad_task_source().queue( + let _ = self.global().task_manager().gamepad_task_source().queue( task!(stop_playing_effect: move || { let actuator = this.root(); let Some(promise) = actuator.playing_effect_promise.borrow_mut().take() else { diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 300c28c636d..632f75c8405 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -138,15 +138,7 @@ use crate::script_runtime::{ use crate::script_thread::{with_script_thread, ScriptThread}; use crate::security_manager::CSPViolationReporter; use crate::task::TaskCanceller; -use crate::task_source::dom_manipulation::DOMManipulationTaskSource; -use crate::task_source::file_reading::FileReadingTaskSource; -use crate::task_source::gamepad::GamepadTaskSource; -use crate::task_source::networking::NetworkingTaskSource; -use crate::task_source::performance_timeline::PerformanceTimelineTaskSource; -use crate::task_source::port_message::PortMessageQueue; -use crate::task_source::remote_event::RemoteEventTaskSource; -use crate::task_source::timer::TimerTaskSource; -use crate::task_source::websocket::WebsocketTaskSource; +use crate::task_manager::TaskManager; use crate::task_source::{TaskSource, TaskSourceName}; use crate::timers::{ IsInterval, OneshotTimerCallback, OneshotTimerHandle, OneshotTimers, TimerCallback, @@ -383,14 +375,14 @@ pub struct GlobalScope { /// A wrapper for glue-code between the ipc router and the event-loop. struct MessageListener { canceller: TaskCanceller, - task_source: PortMessageQueue, + task_source: TaskSource, context: Trusted<GlobalScope>, } /// A wrapper for broadcasts coming in over IPC, and the event-loop. struct BroadcastListener { canceller: TaskCanceller, - task_source: DOMManipulationTaskSource, + task_source: TaskSource, context: Trusted<GlobalScope>, } @@ -398,7 +390,7 @@ struct BroadcastListener { #[derive(Clone)] pub(crate) struct TimerListener { canceller: TaskCanceller, - task_source: TimerTaskSource, + task_source: TaskSource, context: Trusted<GlobalScope>, } @@ -410,7 +402,7 @@ struct FileListener { /// - Some(Empty) => Some(Receiving) => None /// - Some(Empty) => None state: Option<FileListenerState>, - task_source: FileReadingTaskSource, + task_source: TaskSource, task_canceller: TaskCanceller, } @@ -860,7 +852,7 @@ impl GlobalScope { fn timers(&self) -> &OneshotTimers { self.timers.get_or_init(|| { let (task_source, canceller) = ( - self.timer_task_source(), + self.task_manager().timer_task_source(), self.task_canceller(TaskSourceName::Timer), ); OneshotTimers::new( @@ -1102,7 +1094,7 @@ impl GlobalScope { for task in message_buffer { let port_id = *port_id; let this = Trusted::new(self); - let _ = self.port_message_queue().queue( + let _ = self.task_manager().port_message_queue().queue( task!(process_pending_port_messages: move || { let target_global = this.root(); target_global.route_task_to_port(port_id, task, CanGc::note()); @@ -1156,7 +1148,7 @@ impl GlobalScope { if let Some(entangled_id) = entangled_port { // Step 7 let this = Trusted::new(self); - let _ = self.port_message_queue().queue( + let _ = self.task_manager().port_message_queue().queue( task!(post_message: move || { let global = this.root(); // Note: we do this in a task, as this will ensure the global and constellation @@ -1253,7 +1245,7 @@ impl GlobalScope { // to fire the message event let channel = Trusted::new(&*channel); let global = Trusted::new(self); - let _ = self.dom_manipulation_task_source().queue( + let _ = self.task_manager().dom_manipulation_task_source().queue( task!(process_pending_port_messages: move || { let destination = channel.root(); let global = global.root(); @@ -1447,7 +1439,7 @@ impl GlobalScope { ipc::channel().expect("ipc channel failure"); let context = Trusted::new(self); let (task_source, canceller) = ( - self.dom_manipulation_task_source(), + self.task_manager().dom_manipulation_task_source(), self.task_canceller(TaskSourceName::DOMManipulation), ); let listener = BroadcastListener { @@ -1500,7 +1492,7 @@ impl GlobalScope { ipc::channel().expect("ipc channel failure"); let context = Trusted::new(self); let (task_source, canceller) = ( - self.port_message_queue(), + self.task_manager().port_message_queue(), self.task_canceller(TaskSourceName::PortMessage), ); let listener = MessageListener { @@ -1543,7 +1535,7 @@ impl GlobalScope { // Queue a task to complete the transfer, // unless the port is re-transferred in the current task. let this = Trusted::new(self); - let _ = self.port_message_queue().queue( + let _ = self.task_manager().port_message_queue().queue( task!(process_pending_port_messages: move || { let target_global = this.root(); target_global.maybe_add_pending_ports(); @@ -2026,7 +2018,7 @@ impl GlobalScope { let trusted_stream = Trusted::new(&*stream.clone()); let task_canceller = self.task_canceller(TaskSourceName::FileReading); - let task_source = self.file_reading_task_source(); + let task_source = self.task_manager().file_reading_task_source(); let mut file_listener = FileListener { state: Some(FileListenerState::Empty(FileListenerTarget::Stream( @@ -2051,7 +2043,7 @@ impl GlobalScope { let trusted_promise = TrustedPromise::new(promise); let task_canceller = self.task_canceller(TaskSourceName::FileReading); - let task_source = self.file_reading_task_source(); + let task_source = self.task_manager().file_reading_task_source(); let mut file_listener = FileListener { state: Some(FileListenerState::Empty(FileListenerTarget::Promise( @@ -2595,72 +2587,13 @@ impl GlobalScope { unreachable!(); } - /// `TaskSource` to send messages to the gamepad task source of - /// this global scope. - /// <https://w3c.github.io/gamepad/#dfn-gamepad-task-source> - pub fn gamepad_task_source(&self) -> GamepadTaskSource { + /// The [`TaskManager`] used to schedule tasks for this [`GlobalScope`]. + pub fn task_manager(&self) -> &TaskManager { if let Some(window) = self.downcast::<Window>() { - return window.task_manager().gamepad_task_source(); - } - unreachable!(); - } - - /// `TaskSource` to send messages to the networking task source of - /// this global scope. - pub fn networking_task_source(&self) -> NetworkingTaskSource { - if let Some(window) = self.downcast::<Window>() { - return window.task_manager().networking_task_source(); - } - if let Some(worker) = self.downcast::<WorkerGlobalScope>() { - return worker.networking_task_source(); - } - unreachable!(); - } - - /// `TaskSource` to send messages to the port message queue of - /// this global scope. - pub fn port_message_queue(&self) -> PortMessageQueue { - if let Some(window) = self.downcast::<Window>() { - return window.task_manager().port_message_queue(); - } - if let Some(worker) = self.downcast::<WorkerGlobalScope>() { - return worker.port_message_queue(); - } - unreachable!(); - } - - /// `TaskSource` to send messages to the timer queue of - /// this global scope. - pub fn timer_task_source(&self) -> TimerTaskSource { - if let Some(window) = self.downcast::<Window>() { - return window.task_manager().timer_task_source(); - } - if let Some(worker) = self.downcast::<WorkerGlobalScope>() { - return worker.timer_task_source(); - } - unreachable!(); - } - - /// `TaskSource` to send messages to the remote-event task source of - /// this global scope. - pub fn remote_event_task_source(&self) -> RemoteEventTaskSource { - if let Some(window) = self.downcast::<Window>() { - return window.task_manager().remote_event_task_source(); - } - if let Some(worker) = self.downcast::<WorkerGlobalScope>() { - return worker.remote_event_task_source(); - } - unreachable!(); - } - - /// `TaskSource` to send messages to the websocket task source of - /// this global scope. - pub fn websocket_task_source(&self) -> WebsocketTaskSource { - if let Some(window) = self.downcast::<Window>() { - return window.task_manager().websocket_task_source(); + return window.task_manager(); } if let Some(worker) = self.downcast::<WorkerGlobalScope>() { - return worker.websocket_task_source(); + return worker.task_manager(); } unreachable!(); } @@ -2842,7 +2775,8 @@ impl GlobalScope { scripted_caller.line, scripted_caller.col, ); - self.dom_manipulation_task_source() + self.task_manager() + .dom_manipulation_task_source() .queue(task, self) .unwrap(); } @@ -3024,28 +2958,6 @@ impl GlobalScope { unreachable!(); } - pub fn dom_manipulation_task_source(&self) -> DOMManipulationTaskSource { - if let Some(window) = self.downcast::<Window>() { - return window.task_manager().dom_manipulation_task_source(); - } - if let Some(worker) = self.downcast::<WorkerGlobalScope>() { - return worker.dom_manipulation_task_source(); - } - unreachable!(); - } - - /// Channel to send messages to the file reading task source of - /// this of this global scope. - pub fn file_reading_task_source(&self) -> FileReadingTaskSource { - if let Some(window) = self.downcast::<Window>() { - return window.task_manager().file_reading_task_source(); - } - if let Some(worker) = self.downcast::<WorkerGlobalScope>() { - return worker.file_reading_task_source(); - } - unreachable!(); - } - pub fn runtime_handle(&self) -> ParentRuntime { if self.is::<Window>() { ScriptThread::runtime_handle() @@ -3096,18 +3008,6 @@ impl GlobalScope { unreachable!(); } - /// Channel to send messages to the performance timeline task source - /// of this global scope. - pub fn performance_timeline_task_source(&self) -> PerformanceTimelineTaskSource { - if let Some(window) = self.downcast::<Window>() { - return window.task_manager().performance_timeline_task_source(); - } - if let Some(worker) = self.downcast::<WorkerGlobalScope>() { - return worker.performance_timeline_task_source(); - } - unreachable!(); - } - /// <https://w3c.github.io/performance-timeline/#supportedentrytypes-attribute> pub fn supported_performance_entry_types(&self, cx: SafeJSContext, retval: MutableHandleValue) { self.frozen_supported_performance_entry_types.get_or_init( @@ -3261,7 +3161,8 @@ impl GlobalScope { // TODO: 2. If document is not null and is not allowed to use the "gamepad" permission, // then abort these steps. let this = Trusted::new(self); - self.gamepad_task_source() + self.task_manager() + .gamepad_task_source() .queue_with_canceller( task!(gamepad_connected: move || { let global = this.root(); @@ -3291,7 +3192,8 @@ impl GlobalScope { /// <https://www.w3.org/TR/gamepad/#dfn-gamepaddisconnected> pub fn handle_gamepad_disconnect(&self, index: usize) { let this = Trusted::new(self); - self.gamepad_task_source() + self.task_manager() + .gamepad_task_source() .queue_with_canceller( task!(gamepad_disconnected: move || { let global = this.root(); @@ -3315,7 +3217,8 @@ impl GlobalScope { let this = Trusted::new(self); // <https://w3c.github.io/gamepad/#dfn-update-gamepad-state> - self.gamepad_task_source() + self.task_manager() + .gamepad_task_source() .queue_with_canceller( task!(update_gamepad_state: move || { let global = this.root(); @@ -3427,7 +3330,7 @@ impl GlobalScope { &self, request_builder: RequestBuilder, context: Arc<Mutex<Listener>>, - task_source: NetworkingTaskSource, + task_source: TaskSource, cancellation_sender: Option<ipc::IpcReceiver<()>>, ) { let canceller = Some(self.task_canceller(TaskSourceName::Networking)); diff --git a/components/script/dom/htmldetailselement.rs b/components/script/dom/htmldetailselement.rs index 44a8a8fe63a..9d5a1030720 100644 --- a/components/script/dom/htmldetailselement.rs +++ b/components/script/dom/htmldetailselement.rs @@ -20,7 +20,6 @@ use crate::dom::htmlelement::HTMLElement; use crate::dom::node::{window_from_node, Node, NodeDamage}; use crate::dom::virtualmethods::VirtualMethods; use crate::script_runtime::CanGc; -use crate::task_source::TaskSource; #[dom_struct] pub struct HTMLDetailsElement { diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index f1f176daeb6..f5dbe6cd299 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -84,7 +84,6 @@ use crate::dom::window::Window; use crate::links::{get_element_target, LinkRelations}; use crate::script_runtime::CanGc; use crate::script_thread::ScriptThread; -use crate::task_source::TaskSource; #[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)] pub struct GenerationId(u32); diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index fe32f388e1d..a95f49ef2ef 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -98,7 +98,6 @@ use crate::network_listener::{self, PreInvoke, ResourceTimingListener}; use crate::realms::enter_realm; use crate::script_runtime::CanGc; use crate::script_thread::ScriptThread; -use crate::task_source::TaskSource; #[derive(Clone, Copy, Debug)] enum ParseState { diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 18bca9decee..a93d645ee08 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -106,7 +106,6 @@ use crate::network_listener::{self, PreInvoke, ResourceTimingListener}; use crate::realms::{enter_realm, InRealm}; use crate::script_runtime::CanGc; use crate::script_thread::ScriptThread; -use crate::task_source::TaskSource; #[derive(PartialEq)] enum FrameStatus { diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 244a18568c4..3c34ff70d0d 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -67,7 +67,6 @@ use crate::script_module::{ }; use crate::script_runtime::CanGc; use crate::task::TaskCanceller; -use crate::task_source::dom_manipulation::DOMManipulationTaskSource; use crate::task_source::{TaskSource, TaskSourceName}; use crate::unminify::{unminify_js, ScriptSource}; @@ -104,7 +103,7 @@ impl ScriptSource for ScriptOrigin { script_kind: ExternalScriptKind, final_url: ServoUrl, url: ServoUrl, - task_source: DOMManipulationTaskSource, + task_source: TaskSource, canceller: TaskCanceller, script_text: String, fetch_options: ScriptFetchOptions, @@ -478,7 +477,7 @@ impl FetchResponseListener for ClassicContext { script_kind: self.kind, final_url, url: self.url.clone(), - task_source: global.dom_manipulation_task_source(), + task_source: global.task_manager().dom_manipulation_task_source(), canceller: global.task_canceller(TaskSourceName::DOMManipulation), script_text: source_string, fetch_options: self.fetch_options.clone(), diff --git a/components/script/dom/offlineaudiocontext.rs b/components/script/dom/offlineaudiocontext.rs index e6f991001f2..f3deeae2cc9 100644 --- a/components/script/dom/offlineaudiocontext.rs +++ b/components/script/dom/offlineaudiocontext.rs @@ -32,7 +32,6 @@ use crate::dom::promise::Promise; use crate::dom::window::Window; use crate::realms::InRealm; use crate::script_runtime::CanGc; -use crate::task_source::TaskSource; #[dom_struct] pub struct OfflineAudioContext { diff --git a/components/script/dom/performance.rs b/components/script/dom/performance.rs index e9f73f26af4..f5aab785293 100644 --- a/components/script/dom/performance.rs +++ b/components/script/dom/performance.rs @@ -10,6 +10,7 @@ use base::cross_process_instant::CrossProcessInstant; use dom_struct::dom_struct; use time_03::Duration; +use super::bindings::refcounted::Trusted; use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::PerformanceBinding::{ DOMHighResTimeStamp, PerformanceEntryList as DOMPerformanceEntryList, PerformanceMethods, @@ -237,8 +238,16 @@ impl Performance { if !self.pending_notification_observers_task.get() { self.pending_notification_observers_task.set(true); - let task_source = self.global().performance_timeline_task_source(); - task_source.queue_notification(&self.global()); + let task_source = self + .global() + .task_manager() + .performance_timeline_task_source(); + let global = &self.global(); + let owner = Trusted::new(&*global.performance()); + let task = task!(notify_performance_observers: move || { + owner.root().notify_observers(); + }); + let _ = task_source.queue(task, global); } } let mut observers = self.observers.borrow_mut(); @@ -315,8 +324,17 @@ impl Performance { // Step 6. // Queue a new notification task. self.pending_notification_observers_task.set(true); - let task_source = self.global().performance_timeline_task_source(); - task_source.queue_notification(&self.global()); + let task_source = self + .global() + .task_manager() + .performance_timeline_task_source(); + + let global = &self.global(); + let owner = Trusted::new(&*global.performance()); + let task = task!(notify_performance_observers: move || { + owner.root().notify_observers(); + }); + let _ = task_source.queue(task, global); Some(entry_last_index) } diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 8d7fbc4303a..689626f10d2 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -53,7 +53,6 @@ use crate::dom::window::Window; use crate::realms::{enter_realm, InRealm}; use crate::script_runtime::CanGc; use crate::task::TaskCanceller; -use crate::task_source::networking::NetworkingTaskSource; use crate::task_source::TaskSource; #[dom_struct] @@ -81,7 +80,7 @@ pub struct RTCPeerConnection { struct RTCSignaller { trusted: Trusted<RTCPeerConnection>, - task_source: NetworkingTaskSource, + task_source: TaskSource, canceller: TaskCanceller, } diff --git a/components/script/dom/selection.rs b/components/script/dom/selection.rs index a6479404c5c..7347a6464ec 100644 --- a/components/script/dom/selection.rs +++ b/components/script/dom/selection.rs @@ -20,7 +20,6 @@ use crate::dom::eventtarget::EventTarget; use crate::dom::node::{window_from_node, Node}; use crate::dom::range::Range; use crate::script_runtime::CanGc; -use crate::task_source::TaskSource; #[derive(Clone, Copy, JSTraceable, MallocSizeOf)] enum Direction { diff --git a/components/script/dom/serviceworkercontainer.rs b/components/script/dom/serviceworkercontainer.rs index 5158831bdae..7d71f81c5fd 100644 --- a/components/script/dom/serviceworkercontainer.rs +++ b/components/script/dom/serviceworkercontainer.rs @@ -27,7 +27,6 @@ use crate::dom::serviceworkerregistration::ServiceWorkerRegistration; use crate::realms::{enter_realm, InRealm}; use crate::script_runtime::CanGc; use crate::task::TaskCanceller; -use crate::task_source::dom_manipulation::DOMManipulationTaskSource; use crate::task_source::{TaskSource, TaskSourceName}; #[dom_struct] @@ -143,7 +142,7 @@ impl ServiceWorkerContainerMethods<crate::DomTypeHolder> for ServiceWorkerContai // Setup the callback for reject/resolve of the promise, // from steps running "in-parallel" from here in the serviceworker manager. let (task_source, task_canceller) = ( - global.dom_manipulation_task_source(), + global.task_manager().dom_manipulation_task_source(), global.task_canceller(TaskSourceName::DOMManipulation), ); @@ -190,7 +189,7 @@ impl ServiceWorkerContainerMethods<crate::DomTypeHolder> for ServiceWorkerContai /// <https://w3c.github.io/ServiceWorker/#register> struct RegisterJobResultHandler { trusted_promise: Option<TrustedPromise>, - task_source: DOMManipulationTaskSource, + task_source: TaskSource, task_canceller: TaskCanceller, } diff --git a/components/script/dom/serviceworkerglobalscope.rs b/components/script/dom/serviceworkerglobalscope.rs index 1703254b83d..d875d4c6f53 100644 --- a/components/script/dom/serviceworkerglobalscope.rs +++ b/components/script/dom/serviceworkerglobalscope.rs @@ -143,7 +143,7 @@ impl ScriptChan for ServiceWorkerChan { .map_err(|_| ()) } - fn as_boxed(&self) -> Box<dyn ScriptChan + Send> { + fn as_boxed(&self) -> Box<dyn ScriptChan> { Box::new(ServiceWorkerChan { sender: self.sender.clone(), }) diff --git a/components/script/dom/storage.rs b/components/script/dom/storage.rs index d7dbe6f8529..a5865ff72c0 100644 --- a/components/script/dom/storage.rs +++ b/components/script/dom/storage.rs @@ -21,7 +21,6 @@ use crate::dom::event::{Event, EventBubbles, EventCancelable}; use crate::dom::storageevent::StorageEvent; use crate::dom::window::Window; use crate::script_runtime::CanGc; -use crate::task_source::TaskSource; #[dom_struct] pub struct Storage { diff --git a/components/script/dom/subtlecrypto.rs b/components/script/dom/subtlecrypto.rs index df679b72621..344643ef3ce 100644 --- a/components/script/dom/subtlecrypto.rs +++ b/components/script/dom/subtlecrypto.rs @@ -54,7 +54,6 @@ use crate::dom::workerglobalscope::WorkerGlobalScope; use crate::realms::InRealm; use crate::script_runtime::{CanGc, JSContext}; use crate::task::TaskCanceller; -use crate::task_source::dom_manipulation::DOMManipulationTaskSource; use crate::task_source::TaskSource; // String constants for algorithms/curves @@ -142,13 +141,13 @@ impl SubtleCrypto { ) } - fn task_source_with_canceller(&self) -> (DOMManipulationTaskSource, TaskCanceller) { + fn task_source_with_canceller(&self) -> (TaskSource, TaskCanceller) { if let Some(window) = self.global().downcast::<Window>() { window .task_manager() .dom_manipulation_task_source_with_canceller() } else if let Some(worker_global) = self.global().downcast::<WorkerGlobalScope>() { - let task_source = worker_global.dom_manipulation_task_source(); + let task_source = worker_global.task_manager().dom_manipulation_task_source(); let canceller = worker_global.task_canceller(); (task_source, canceller) } else { diff --git a/components/script/dom/texttracklist.rs b/components/script/dom/texttracklist.rs index d938b8e1dfd..eae7b136cc2 100644 --- a/components/script/dom/texttracklist.rs +++ b/components/script/dom/texttracklist.rs @@ -18,7 +18,6 @@ use crate::dom::texttrack::TextTrack; use crate::dom::trackevent::TrackEvent; use crate::dom::window::Window; use crate::script_runtime::CanGc; -use crate::task_source::TaskSource; #[dom_struct] pub struct TextTrackList { diff --git a/components/script/dom/videotracklist.rs b/components/script/dom/videotracklist.rs index 650c5ffe526..52a8d212bce 100644 --- a/components/script/dom/videotracklist.rs +++ b/components/script/dom/videotracklist.rs @@ -16,7 +16,6 @@ use crate::dom::htmlmediaelement::HTMLMediaElement; use crate::dom::videotrack::VideoTrack; use crate::dom::window::Window; use crate::script_runtime::CanGc; -use crate::task_source::TaskSource; #[dom_struct] pub struct VideoTrackList { diff --git a/components/script/dom/webglquery.rs b/components/script/dom/webglquery.rs index e11e7766e93..1f416a3837d 100644 --- a/components/script/dom/webglquery.rs +++ b/components/script/dom/webglquery.rs @@ -16,7 +16,6 @@ use crate::dom::bindings::root::DomRoot; use crate::dom::webglobject::WebGLObject; use crate::dom::webglrenderingcontext::{Operation, WebGLRenderingContext}; use crate::script_runtime::CanGc; -use crate::task_source::TaskSource; #[dom_struct] pub struct WebGLQuery { diff --git a/components/script/dom/webglsync.rs b/components/script/dom/webglsync.rs index 42e1e51c852..5f07c0620a5 100644 --- a/components/script/dom/webglsync.rs +++ b/components/script/dom/webglsync.rs @@ -15,7 +15,6 @@ use crate::dom::bindings::root::DomRoot; use crate::dom::webglobject::WebGLObject; use crate::dom::webglrenderingcontext::{Operation, WebGLRenderingContext}; use crate::script_runtime::CanGc; -use crate::task_source::TaskSource; #[dom_struct] pub struct WebGLSync { diff --git a/components/script/dom/webgpu/gpu.rs b/components/script/dom/webgpu/gpu.rs index 5ee5d047113..ba4ce6be221 100644 --- a/components/script/dom/webgpu/gpu.rs +++ b/components/script/dom/webgpu/gpu.rs @@ -25,7 +25,7 @@ use crate::dom::promise::Promise; use crate::dom::webgpu::gpuadapter::GPUAdapter; use crate::realms::InRealm; use crate::script_runtime::CanGc; -use crate::task_source::{TaskSource, TaskSourceName}; +use crate::task_source::TaskSourceName; #[dom_struct] #[allow(clippy::upper_case_acronyms)] @@ -69,7 +69,10 @@ pub fn response_async<T: AsyncWGPUListener + DomObject + 'static>( receiver: &T, ) -> IpcSender<WebGPUResponse> { let (action_sender, action_receiver) = ipc::channel().unwrap(); - let task_source = receiver.global().dom_manipulation_task_source(); + let task_source = receiver + .global() + .task_manager() + .dom_manipulation_task_source(); let canceller = receiver .global() .task_canceller(TaskSourceName::DOMManipulation); diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index d8b186057b6..9aa293c29f3 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -38,11 +38,9 @@ use crate::dom::event::{Event, EventBubbles, EventCancelable}; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::messageevent::MessageEvent; -use crate::script_runtime::ScriptThreadEventCategory::WebSocketEvent; -use crate::script_runtime::{CanGc, CommonScriptMsg}; +use crate::script_runtime::CanGc; use crate::task::{TaskCanceller, TaskOnce}; -use crate::task_source::websocket::WebsocketTaskSource; -use crate::task_source::TaskSource; +use crate::task_source::{TaskSource, TaskSourceName}; #[derive(Clone, Copy, Debug, JSTraceable, MallocSizeOf, PartialEq)] enum WebSocketRequestState { @@ -72,7 +70,7 @@ mod close_code { fn close_the_websocket_connection( address: Trusted<WebSocket>, - task_source: &WebsocketTaskSource, + task_source: &TaskSource, canceller: &TaskCanceller, code: Option<u16>, reason: String, @@ -88,7 +86,7 @@ fn close_the_websocket_connection( fn fail_the_websocket_connection( address: Trusted<WebSocket>, - task_source: &WebsocketTaskSource, + task_source: &TaskSource, canceller: &TaskCanceller, ) { let close_task = CloseTask { @@ -168,19 +166,12 @@ impl WebSocket { if !self.clearing_buffer.get() && self.ready_state.get() == WebSocketRequestState::Open { self.clearing_buffer.set(true); - let task = Box::new(BufferedAmountTask { address }); - - let pipeline_id = self.global().pipeline_id(); - self.global() - .script_chan() - // TODO: Use a dedicated `websocket-task-source` task source instead. - .send(CommonScriptMsg::Task( - WebSocketEvent, - task, - Some(pipeline_id), - WebsocketTaskSource::NAME, - )) - .unwrap(); + // TODO(mrobinson): Should this task be cancellable? + let _ = self + .global() + .task_manager() + .websocket_task_source() + .queue_unconditionally(BufferedAmountTask { address }); } Ok(true) @@ -284,8 +275,8 @@ impl WebSocketMethods<crate::DomTypeHolder> for WebSocket { .core_resource_thread() .send(CoreResourceMsg::Fetch(request, channels)); - let task_source = global.websocket_task_source(); - let canceller = global.task_canceller(WebsocketTaskSource::NAME); + let task_source = global.task_manager().websocket_task_source(); + let canceller = global.task_canceller(TaskSourceName::WebSocket); ROUTER.add_typed_route( dom_event_receiver.to_ipc_receiver(), Box::new(move |message| match message.unwrap() { @@ -451,11 +442,11 @@ impl WebSocketMethods<crate::DomTypeHolder> for WebSocket { // TODO: use a dedicated task source, // https://html.spec.whatwg.org/multipage/#websocket-task-source // When making the switch, also update the task_canceller call. - let task_source = self.global().websocket_task_source(); + let task_source = self.global().task_manager().websocket_task_source(); fail_the_websocket_connection( address, &task_source, - &self.global().task_canceller(WebsocketTaskSource::NAME), + &self.global().task_canceller(TaskSourceName::WebSocket), ); }, WebSocketRequestState::Open => { diff --git a/components/script/dom/webxr/fakexrdevice.rs b/components/script/dom/webxr/fakexrdevice.rs index 194ba0bd087..04440086f90 100644 --- a/components/script/dom/webxr/fakexrdevice.rs +++ b/components/script/dom/webxr/fakexrdevice.rs @@ -35,7 +35,6 @@ use crate::dom::fakexrinputcontroller::{init_to_mock_buttons, FakeXRInputControl use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; use crate::script_runtime::CanGc; -use crate::task_source::TaskSource; #[dom_struct] pub struct FakeXRDevice { diff --git a/components/script/dom/webxr/xrsession.rs b/components/script/dom/webxr/xrsession.rs index 92ac419c585..f3b8a3ce32c 100644 --- a/components/script/dom/webxr/xrsession.rs +++ b/components/script/dom/webxr/xrsession.rs @@ -68,7 +68,6 @@ use crate::dom::xrsessionevent::XRSessionEvent; use crate::dom::xrspace::XRSpace; use crate::realms::InRealm; use crate::script_runtime::JSContext; -use crate::task_source::TaskSource; use crate::script_runtime::CanGc; #[dom_struct] diff --git a/components/script/dom/webxr/xrsystem.rs b/components/script/dom/webxr/xrsystem.rs index fb28b477e39..82bf4e5d37e 100644 --- a/components/script/dom/webxr/xrsystem.rs +++ b/components/script/dom/webxr/xrsystem.rs @@ -35,7 +35,6 @@ use crate::dom::xrtest::XRTest; use crate::realms::InRealm; use crate::script_runtime::CanGc; use crate::script_thread::ScriptThread; -use crate::task_source::TaskSource; #[dom_struct] pub struct XRSystem { diff --git a/components/script/dom/webxr/xrtest.rs b/components/script/dom/webxr/xrtest.rs index 02c090b2a1f..b56049b6dff 100644 --- a/components/script/dom/webxr/xrtest.rs +++ b/components/script/dom/webxr/xrtest.rs @@ -28,7 +28,6 @@ use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; use crate::script_runtime::CanGc; use crate::script_thread::ScriptThread; -use crate::task_source::TaskSource; #[dom_struct] pub struct XRTest { diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index ce10d7cc157..fc3d13e60eb 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -158,7 +158,7 @@ use crate::script_runtime::{ }; use crate::script_thread::ScriptThread; use crate::task_manager::TaskManager; -use crate::task_source::{TaskSource, TaskSourceName}; +use crate::task_source::TaskSourceName; use crate::timers::{IsInterval, TimerCallback}; use crate::unminify::unminified_path; use crate::webdriver_handlers::jsval_to_webdriver; diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 7fd73750de7..abe993ad06a 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use std::cell::{RefCell, RefMut}; +use std::cell::{OnceCell, RefCell, RefMut}; use std::default::Default; use std::rc::Rc; use std::sync::atomic::{AtomicBool, Ordering}; @@ -44,7 +44,7 @@ use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::{DomRoot, MutNullableDom}; use crate::dom::bindings::settings_stack::AutoEntryScript; use crate::dom::bindings::str::{DOMString, USVString}; -use crate::dom::bindings::trace::RootedTraceableBox; +use crate::dom::bindings::trace::{CustomTraceable, RootedTraceableBox}; use crate::dom::crypto::Crypto; use crate::dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope; use crate::dom::globalscope::GlobalScope; @@ -60,14 +60,7 @@ use crate::fetch; use crate::realms::{enter_realm, InRealm}; use crate::script_runtime::{CanGc, CommonScriptMsg, JSContext, Runtime, ScriptChan, ScriptPort}; use crate::task::TaskCanceller; -use crate::task_source::dom_manipulation::DOMManipulationTaskSource; -use crate::task_source::file_reading::FileReadingTaskSource; -use crate::task_source::networking::NetworkingTaskSource; -use crate::task_source::performance_timeline::PerformanceTimelineTaskSource; -use crate::task_source::port_message::PortMessageQueue; -use crate::task_source::remote_event::RemoteEventTaskSource; -use crate::task_source::timer::TimerTaskSource; -use crate::task_source::websocket::WebsocketTaskSource; +use crate::task_manager::TaskManager; use crate::timers::{IsInterval, TimerCallback}; pub fn prepare_workerscope_init( @@ -135,6 +128,9 @@ pub struct WorkerGlobalScope { /// Timers are handled in the service worker event loop. #[no_trace] timer_scheduler: RefCell<TimerScheduler>, + + /// A [`TaskManager`] for this [`WorkerGlobalScope`]. + task_manager: OnceCell<TaskManager>, } impl WorkerGlobalScope { @@ -189,6 +185,7 @@ impl WorkerGlobalScope { navigation_start: CrossProcessInstant::now(), performance: Default::default(), timer_scheduler: RefCell::default(), + task_manager: Default::default(), } } @@ -510,36 +507,9 @@ impl WorkerGlobalScope { } } - pub fn dom_manipulation_task_source(&self) -> DOMManipulationTaskSource { - DOMManipulationTaskSource(self.script_chan(), self.pipeline_id()) - } - - pub fn file_reading_task_source(&self) -> FileReadingTaskSource { - FileReadingTaskSource(self.script_chan(), self.pipeline_id()) - } - - pub fn networking_task_source(&self) -> NetworkingTaskSource { - NetworkingTaskSource(self.script_chan(), self.pipeline_id()) - } - - pub fn performance_timeline_task_source(&self) -> PerformanceTimelineTaskSource { - PerformanceTimelineTaskSource(self.script_chan(), self.pipeline_id()) - } - - pub fn port_message_queue(&self) -> PortMessageQueue { - PortMessageQueue(self.script_chan(), self.pipeline_id()) - } - - pub fn timer_task_source(&self) -> TimerTaskSource { - TimerTaskSource(self.script_chan(), self.pipeline_id()) - } - - pub fn remote_event_task_source(&self) -> RemoteEventTaskSource { - RemoteEventTaskSource(self.script_chan(), self.pipeline_id()) - } - - pub fn websocket_task_source(&self) -> WebsocketTaskSource { - WebsocketTaskSource(self.script_chan(), self.pipeline_id()) + pub(crate) fn task_manager(&self) -> &TaskManager { + self.task_manager + .get_or_init(|| TaskManager::new(self.script_chan(), self.pipeline_id())) } pub fn new_script_pair(&self) -> (Box<dyn ScriptChan + Send>, Box<dyn ScriptPort + Send>) { diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index a031b625036..d27fc3c06ca 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -73,7 +73,7 @@ use crate::dom::xmlhttprequestupload::XMLHttpRequestUpload; use crate::fetch::FetchCanceller; use crate::network_listener::{self, PreInvoke, ResourceTimingListener}; use crate::script_runtime::{CanGc, JSContext}; -use crate::task_source::networking::NetworkingTaskSource; +use crate::task_source::{TaskSource, TaskSourceName}; use crate::timers::{OneshotTimerCallback, OneshotTimerHandle}; #[derive(Clone, Copy, Debug, JSTraceable, MallocSizeOf, PartialEq)] @@ -294,7 +294,7 @@ impl XMLHttpRequest { fn initiate_async_xhr( context: Arc<Mutex<XHRContext>>, - task_source: NetworkingTaskSource, + task_source: TaskSource, global: &GlobalScope, init: RequestBuilder, cancellation_chan: ipc::IpcReceiver<()>, @@ -1560,10 +1560,17 @@ impl XMLHttpRequest { })); let (task_source, script_port) = if self.sync.get() { - let (tx, rx) = global.new_script_pair(); - (NetworkingTaskSource(tx, global.pipeline_id()), Some(rx)) + let (sender, receiver) = global.new_script_pair(); + ( + TaskSource { + sender, + pipeline_id: global.pipeline_id(), + name: TaskSourceName::Networking, + }, + Some(receiver), + ) } else { - (global.networking_task_source(), None) + (global.task_manager().networking_task_source(), None) }; let cancel_receiver = self.canceller.borrow_mut().initialize(); |