diff --git a/components/script/dom/analysernode.rs b/components/script/dom/analysernode.rs index cf04bd44fcac..06ff08d9af20 100644 --- a/components/script/dom/analysernode.rs +++ b/components/script/dom/analysernode.rs @@ -17,7 +17,7 @@ use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::reflector::reflect_dom_object; use crate::dom::bindings::root::DomRoot; use crate::dom::window::Window; -use crate::task_source::{TaskSource, TaskSourceName}; +use crate::task_source::TaskSource; use dom_struct::dom_struct; use ipc_channel::ipc::{self, IpcReceiver}; use ipc_channel::router::ROUTER; @@ -97,8 +97,9 @@ impl AnalyserNode { ) -> Fallible> { let (node, recv) = AnalyserNode::new_inherited(window, context, options)?; let object = reflect_dom_object(Box::new(node), window, AnalyserNodeBinding::Wrap); - let source = window.dom_manipulation_task_source(); - let canceller = window.task_canceller(TaskSourceName::DOMManipulation); + let (source, canceller) = window + .task_manager() + .dom_manipulation_task_source_with_canceller(); let this = Trusted::new(&*object); ROUTER.add_route( diff --git a/components/script/dom/audiocontext.rs b/components/script/dom/audiocontext.rs index 03cdb5161390..9bb4f16ce678 100644 --- a/components/script/dom/audiocontext.rs +++ b/components/script/dom/audiocontext.rs @@ -126,7 +126,7 @@ impl AudioContextMethods for AudioContext { // Steps 4 and 5. let window = DomRoot::downcast::(self.global()).unwrap(); - let task_source = window.dom_manipulation_task_source(); + let task_source = window.task_manager().dom_manipulation_task_source(); let trusted_promise = TrustedPromise::new(promise.clone()); match self.context.audio_context_impl().suspend() { Ok(_) => { @@ -141,7 +141,7 @@ impl AudioContextMethods for AudioContext { if base_context.State() != AudioContextState::Suspended { base_context.set_state_attribute(AudioContextState::Suspended); let window = DomRoot::downcast::(context.global()).unwrap(); - window.dom_manipulation_task_source().queue_simple_event( + window.task_manager().dom_manipulation_task_source().queue_simple_event( context.upcast(), atom!("statechange"), &window @@ -188,7 +188,7 @@ impl AudioContextMethods for AudioContext { // Steps 4 and 5. let window = DomRoot::downcast::(self.global()).unwrap(); - let task_source = window.dom_manipulation_task_source(); + let task_source = window.task_manager().dom_manipulation_task_source(); let trusted_promise = TrustedPromise::new(promise.clone()); match self.context.audio_context_impl().close() { Ok(_) => { @@ -203,7 +203,7 @@ impl AudioContextMethods for AudioContext { if base_context.State() != AudioContextState::Closed { base_context.set_state_attribute(AudioContextState::Closed); let window = DomRoot::downcast::(context.global()).unwrap(); - window.dom_manipulation_task_source().queue_simple_event( + window.task_manager().dom_manipulation_task_source().queue_simple_event( context.upcast(), atom!("statechange"), &window diff --git a/components/script/dom/audioscheduledsourcenode.rs b/components/script/dom/audioscheduledsourcenode.rs index 31527fda3de5..24437b88db94 100644 --- a/components/script/dom/audioscheduledsourcenode.rs +++ b/components/script/dom/audioscheduledsourcenode.rs @@ -10,7 +10,7 @@ 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, TaskSourceName}; +use crate::task_source::TaskSource; use dom_struct::dom_struct; use servo_media::audio::node::OnEndedCallback; use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage}; @@ -71,15 +71,16 @@ impl AudioScheduledSourceNodeMethods for AudioScheduledSourceNode { let this = Trusted::new(self); let global = self.global(); let window = global.as_window(); - let task_source = window.dom_manipulation_task_source(); - let canceller = window.task_canceller(TaskSourceName::DOMManipulation); + let (task_source, canceller) = window + .task_manager() + .dom_manipulation_task_source_with_canceller(); let callback = OnEndedCallback::new(move || { let _ = task_source.queue_with_canceller( task!(ended: move || { let this = this.root(); let global = this.global(); let window = global.as_window(); - window.dom_manipulation_task_source().queue_simple_event( + window.task_manager().dom_manipulation_task_source().queue_simple_event( this.upcast(), atom!("ended"), &window diff --git a/components/script/dom/baseaudiocontext.rs b/components/script/dom/baseaudiocontext.rs index 68acce4d2554..6706bac28be6 100644 --- a/components/script/dom/baseaudiocontext.rs +++ b/components/script/dom/baseaudiocontext.rs @@ -40,7 +40,7 @@ use crate::dom::oscillatornode::OscillatorNode; use crate::dom::pannernode::PannerNode; use crate::dom::promise::Promise; use crate::dom::window::Window; -use crate::task_source::{TaskSource, TaskSourceName}; +use crate::task_source::TaskSource; use dom_struct::dom_struct; use js::rust::CustomAutoRooterGuard; use js::typedarray::ArrayBuffer; @@ -213,7 +213,7 @@ impl BaseAudioContext { pub fn resume(&self) { let global = self.global(); let window = global.as_window(); - let task_source = window.dom_manipulation_task_source(); + let task_source = window.task_manager().dom_manipulation_task_source(); let this = Trusted::new(self); // Set the rendering thread state to 'running' and start // rendering the audio graph. @@ -227,7 +227,7 @@ impl BaseAudioContext { if this.state.get() != AudioContextState::Running { this.state.set(AudioContextState::Running); let window = DomRoot::downcast::(this.global()).unwrap(); - window.dom_manipulation_task_source().queue_simple_event( + window.task_manager().dom_manipulation_task_source().queue_simple_event( this.upcast(), atom!("statechange"), &window @@ -428,10 +428,12 @@ impl BaseAudioContextMethods for BaseAudioContext { let decoded_audio__ = decoded_audio.clone(); let this = Trusted::new(self); let this_ = this.clone(); - let task_source = window.dom_manipulation_task_source(); - let task_source_ = window.dom_manipulation_task_source(); - let canceller = window.task_canceller(TaskSourceName::DOMManipulation); - let canceller_ = window.task_canceller(TaskSourceName::DOMManipulation); + let (task_source, canceller) = window + .task_manager() + .dom_manipulation_task_source_with_canceller(); + let (task_source_, canceller_) = window + .task_manager() + .dom_manipulation_task_source_with_canceller(); let callbacks = AudioDecoderCallbacks::new() .ready(move |channel_count| { decoded_audio diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 36156a1d89f7..a18da3f112fc 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -521,6 +521,7 @@ impl Document { if self.ready_state.get() == DocumentReadyState::Complete { let document = Trusted::new(self); self.window + .task_manager() .dom_manipulation_task_source() .queue( task!(fire_pageshow_event: move || { @@ -1869,6 +1870,7 @@ impl Document { debug!("Document loads are complete."); let document = Trusted::new(self); self.window + .task_manager() .dom_manipulation_task_source() .queue( task!(fire_load_event: move || { @@ -1922,6 +1924,7 @@ impl Document { let document = Trusted::new(self); if document.root().browsing_context().is_some() { self.window + .task_manager() .dom_manipulation_task_source() .queue( task!(fire_pageshow_event: move || { @@ -2104,13 +2107,16 @@ impl Document { // Step 4.1. let window = self.window(); - window.dom_manipulation_task_source().queue_event( - self.upcast(), - atom!("DOMContentLoaded"), - EventBubbles::Bubbles, - EventCancelable::NotCancelable, - window, - ); + window + .task_manager() + .dom_manipulation_task_source() + .queue_event( + self.upcast(), + atom!("DOMContentLoaded"), + EventBubbles::Bubbles, + EventCancelable::NotCancelable, + window, + ); window.reflow(ReflowGoal::Full, ReflowReason::DOMContentLoaded); update_with_current_time_ms(&self.dom_content_loaded_event_end); diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 5d2ed77ce4dd..bca3f36f68ea 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -476,7 +476,7 @@ impl GlobalScope { /// this global scope. pub fn networking_task_source(&self) -> NetworkingTaskSource { if let Some(window) = self.downcast::() { - return window.networking_task_source(); + return window.task_manager().networking_task_source(); } if let Some(worker) = self.downcast::() { return worker.networking_task_source(); @@ -488,7 +488,7 @@ impl GlobalScope { /// this global scope. pub fn remote_event_task_source(&self) -> RemoteEventTaskSource { if let Some(window) = self.downcast::() { - return window.remote_event_task_source(); + return window.task_manager().remote_event_task_source(); } if let Some(worker) = self.downcast::() { return worker.remote_event_task_source(); @@ -500,7 +500,7 @@ impl GlobalScope { /// this global scope. pub fn websocket_task_source(&self) -> WebsocketTaskSource { if let Some(window) = self.downcast::() { - return window.websocket_task_source(); + return window.task_manager().websocket_task_source(); } if let Some(worker) = self.downcast::() { return worker.websocket_task_source(); @@ -635,7 +635,7 @@ impl GlobalScope { /// properly cancelled when the global scope is destroyed. pub fn task_canceller(&self, name: TaskSourceName) -> TaskCanceller { if let Some(window) = self.downcast::() { - return window.task_canceller(name); + return window.task_manager().task_canceller(name); } if let Some(worker) = self.downcast::() { // Note: the "name" is not passed to the worker, @@ -691,7 +691,7 @@ impl GlobalScope { pub fn dom_manipulation_task_source(&self) -> DOMManipulationTaskSource { if let Some(window) = self.downcast::() { - return window.dom_manipulation_task_source(); + return window.task_manager().dom_manipulation_task_source(); } if let Some(worker) = self.downcast::() { return worker.dom_manipulation_task_source(); @@ -703,7 +703,7 @@ impl GlobalScope { /// this of this global scope. pub fn file_reading_task_source(&self) -> FileReadingTaskSource { if let Some(window) = self.downcast::() { - return window.file_reading_task_source(); + return window.task_manager().file_reading_task_source(); } if let Some(worker) = self.downcast::() { return worker.file_reading_task_source(); @@ -756,7 +756,7 @@ impl GlobalScope { /// of this global scope. pub fn performance_timeline_task_source(&self) -> PerformanceTimelineTaskSource { if let Some(window) = self.downcast::() { - return window.performance_timeline_task_source(); + return window.task_manager().performance_timeline_task_source(); } if let Some(worker) = self.downcast::() { return worker.performance_timeline_task_source(); diff --git a/components/script/dom/htmldetailselement.rs b/components/script/dom/htmldetailselement.rs index 3f7021dc786a..e30b8ef4c521 100644 --- a/components/script/dom/htmldetailselement.rs +++ b/components/script/dom/htmldetailselement.rs @@ -76,7 +76,7 @@ impl VirtualMethods for HTMLDetailsElement { let window = window_from_node(self); let this = Trusted::new(self); // FIXME(nox): Why are errors silenced here? - let _ = window.dom_manipulation_task_source().queue( + let _ = window.task_manager().dom_manipulation_task_source().queue( task!(details_notification_task_steps: move || { let this = this.root(); if counter == this.toggle_counter.get() { diff --git a/components/script/dom/htmldialogelement.rs b/components/script/dom/htmldialogelement.rs index 36edbefa9cbf..b7fdb090ba5f 100644 --- a/components/script/dom/htmldialogelement.rs +++ b/components/script/dom/htmldialogelement.rs @@ -90,7 +90,8 @@ impl HTMLDialogElementMethods for HTMLDialogElement { // TODO: Step 4 implement pending dialog stack removal // Step 5 - win.dom_manipulation_task_source() + win.task_manager() + .dom_manipulation_task_source() .queue_simple_event(target, atom!("close"), &win); } } diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index fc9e4832fe57..c335a06d0cc9 100755 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -523,6 +523,7 @@ impl HTMLFormElement { // Step 3. target + .task_manager() .dom_manipulation_task_source() .queue(task, target.upcast()) .unwrap(); diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 9cae4e83e7a0..252f8a6b5aab 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -237,7 +237,7 @@ impl HTMLIFrameElement { let this = Trusted::new(self); let pipeline_id = self.pipeline_id().unwrap(); // FIXME(nox): Why are errors silenced here? - let _ = window.dom_manipulation_task_source().queue( + let _ = window.task_manager().dom_manipulation_task_source().queue( task!(iframe_load_event_steps: move || { this.root().iframe_load_event_steps(pipeline_id); }), diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 851f9971455a..7fd95a57f30a 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -40,7 +40,7 @@ use crate::dom::window::Window; use crate::microtask::{Microtask, MicrotaskRunnable}; use crate::network_listener::{NetworkListener, PreInvoke}; use crate::script_thread::ScriptThread; -use crate::task_source::{TaskSource, TaskSourceName}; +use crate::task_source::TaskSource; use cssparser::{Parser, ParserInput}; use dom_struct::dom_struct; use euclid::Point2D; @@ -237,8 +237,9 @@ impl HTMLImageElement { let (responder_sender, responder_receiver) = ipc::channel().unwrap(); let window = window_from_node(elem); - let task_source = window.networking_task_source(); - let task_canceller = window.task_canceller(TaskSourceName::Networking); + let (task_source, canceller) = window + .task_manager() + .networking_task_source_with_canceller(); let generation = elem.generation.get(); ROUTER.add_route( responder_receiver.to_opaque(), @@ -257,7 +258,7 @@ impl HTMLImageElement { element.process_image_response(image); } }), - &task_canceller, + &canceller, ); }), ); @@ -308,10 +309,14 @@ impl HTMLImageElement { })); let (action_sender, action_receiver) = ipc::channel().unwrap(); + let (task_source, canceller) = document + .window() + .task_manager() + .networking_task_source_with_canceller(); let listener = NetworkListener { - context: context, - task_source: window.networking_task_source(), - canceller: Some(window.task_canceller(TaskSourceName::Networking)), + context, + task_source, + canceller: Some(canceller), }; ROUTER.add_route( action_receiver.to_opaque(), @@ -780,7 +785,7 @@ impl HTMLImageElement { fn update_the_image_data_sync_steps(&self) { let document = document_from_node(self); let window = document.window(); - let task_source = window.dom_manipulation_task_source(); + let task_source = window.task_manager().dom_manipulation_task_source(); let this = Trusted::new(self); let (src, pixel_density) = match self.select_image_source() { // Step 8 @@ -938,7 +943,7 @@ impl HTMLImageElement { current_request.current_pixel_density = pixel_density; let this = Trusted::new(self); let src = String::from(src); - let _ = window.dom_manipulation_task_source().queue( + let _ = window.task_manager().dom_manipulation_task_source().queue( task!(image_load_event: move || { let this = this.root(); { @@ -989,8 +994,9 @@ impl HTMLImageElement { let (responder_sender, responder_receiver) = ipc::channel().unwrap(); let window = window_from_node(elem); - let task_source = window.networking_task_source(); - let task_canceller = window.task_canceller(TaskSourceName::Networking); + let (task_source, canceller) = window + .task_manager() + .networking_task_source_with_canceller(); let generation = elem.generation.get(); ROUTER.add_route(responder_receiver.to_opaque(), Box::new(move |message| { debug!("Got image {:?}", message); @@ -1008,7 +1014,7 @@ impl HTMLImageElement { DOMString::from_string(selected_source_clone), generation, selected_pixel_density); } }), - &task_canceller, + &canceller, ); })); @@ -1133,7 +1139,7 @@ impl HTMLImageElement { let this = Trusted::new(self); let window = window_from_node(self); let src = src.to_string(); - let _ = window.dom_manipulation_task_source().queue( + let _ = window.task_manager().dom_manipulation_task_source().queue( task!(image_load_event: move || { let this = this.root(); let relevant_mutation = this.generation.get() != generation; diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 3b2a3e015524..d7110183c4a6 100755 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -1515,13 +1515,16 @@ impl VirtualMethods for HTMLInputElement { { if event.IsTrusted() { let window = window_from_node(self); - let _ = window.user_interaction_task_source().queue_event( - &self.upcast(), - atom!("input"), - EventBubbles::Bubbles, - EventCancelable::NotCancelable, - &window, - ); + let _ = window + .task_manager() + .user_interaction_task_source() + .queue_event( + &self.upcast(), + atom!("input"), + EventBubbles::Bubbles, + EventCancelable::NotCancelable, + &window, + ); } } } diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index b178b4b58019..a91487d55551 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -36,7 +36,7 @@ use crate::fetch::FetchCanceller; use crate::microtask::{Microtask, MicrotaskRunnable}; use crate::network_listener::{NetworkListener, PreInvoke}; use crate::script_thread::ScriptThread; -use crate::task_source::{TaskSource, TaskSourceName}; +use crate::task_source::TaskSource; use dom_struct::dom_struct; use headers_core::HeaderMapExt; use headers_ext::ContentLength; @@ -295,7 +295,7 @@ impl HTMLMediaElement { let window = window_from_node(self); // FIXME(nox): Why are errors silenced here? - let task_source = window.media_element_task_source(); + let task_source = window.task_manager().media_element_task_source(); if self.Paused() { // Step 6.1. self.paused.set(false); @@ -373,7 +373,7 @@ impl HTMLMediaElement { let window = window_from_node(self); let this = Trusted::new(self); let generation_id = self.generation_id.get(); - let _ = window.media_element_task_source().queue( + let _ = window.task_manager().media_element_task_source().queue( task!(internal_pause_steps: move || { let this = this.root(); if generation_id != this.generation_id.get() { @@ -415,7 +415,7 @@ impl HTMLMediaElement { let this = Trusted::new(self); let generation_id = self.generation_id.get(); // FIXME(nox): Why are errors silenced here? - let _ = window.media_element_task_source().queue( + let _ = window.task_manager().media_element_task_source().queue( task!(notify_about_playing: move || { let this = this.root(); if generation_id != this.generation_id.get() { @@ -449,7 +449,7 @@ impl HTMLMediaElement { } let window = window_from_node(self); - let task_source = window.media_element_task_source(); + let task_source = window.task_manager().media_element_task_source(); // Step 1. match (old_ready_state, ready_state) { @@ -604,11 +604,10 @@ impl HTMLMediaElement { // Step 8. let window = window_from_node(self); - window.media_element_task_source().queue_simple_event( - self.upcast(), - atom!("loadstart"), - &window, - ); + window + .task_manager() + .media_element_task_source() + .queue_simple_event(self.upcast(), atom!("loadstart"), &window); // Step 9. match mode { @@ -710,10 +709,13 @@ impl HTMLMediaElement { let context = Arc::new(Mutex::new(HTMLMediaElementContext::new(self))); let (action_sender, action_receiver) = ipc::channel().unwrap(); let window = window_from_node(self); + let (task_source, canceller) = window + .task_manager() + .networking_task_source_with_canceller(); let listener = NetworkListener { context, - task_source: window.networking_task_source(), - canceller: Some(window.task_canceller(TaskSourceName::Networking)), + task_source, + canceller: Some(canceller), }; ROUTER.add_route( action_receiver.to_opaque(), @@ -768,15 +770,15 @@ impl HTMLMediaElement { // Step 4.remote.1.2. let window = window_from_node(self); - window.media_element_task_source().queue_simple_event( - self.upcast(), - atom!("suspend"), - &window, - ); + window + .task_manager() + .media_element_task_source() + .queue_simple_event(self.upcast(), atom!("suspend"), &window); // Step 4.remote.1.3. let this = Trusted::new(self); window + .task_manager() .media_element_task_source() .queue( task!(set_media_delay_load_event_flag_to_false: move || { @@ -817,7 +819,7 @@ impl HTMLMediaElement { let generation_id = self.generation_id.get(); self.take_pending_play_promises(Err(Error::NotSupported)); // FIXME(nox): Why are errors silenced here? - let _ = window.media_element_task_source().queue( + let _ = window.task_manager().media_element_task_source().queue( task!(dedicated_media_source_failure_steps: move || { let this = this.root(); if generation_id != this.generation_id.get() { @@ -874,7 +876,7 @@ impl HTMLMediaElement { } let window = window_from_node(self); - let task_source = window.media_element_task_source(); + let task_source = window.task_manager().media_element_task_source(); // Step 5. let network_state = self.network_state.get(); @@ -1051,7 +1053,7 @@ impl HTMLMediaElement { // Step 10. let window = window_from_node(self); - let task_source = window.media_element_task_source(); + let task_source = window.task_manager().media_element_task_source(); task_source.queue_simple_event(self.upcast(), atom!("seeking"), &window); // Step 11. @@ -1074,7 +1076,7 @@ impl HTMLMediaElement { // Step 16. let window = window_from_node(self); - let task_source = window.media_element_task_source(); + let task_source = window.task_manager().media_element_task_source(); task_source.queue_simple_event(self.upcast(), atom!("timeupdate"), &window); // Step 17. @@ -1090,8 +1092,9 @@ impl HTMLMediaElement { let trusted_node = Trusted::new(self); let window = window_from_node(self); - let task_source = window.media_element_task_source(); - let task_canceller = window.task_canceller(TaskSourceName::DOMManipulation); + let (task_source, canceller) = window + .task_manager() + .dom_manipulation_task_source_with_canceller(); ROUTER.add_route( action_receiver.to_opaque(), Box::new(move |message| { @@ -1102,7 +1105,7 @@ impl HTMLMediaElement { task!(handle_player_event: move || { this.root().handle_player_event(&event); }), - &task_canceller, + &canceller, ) .unwrap(); }), @@ -1134,7 +1137,7 @@ impl HTMLMediaElement { } if previous_duration != self.duration.get() { let window = window_from_node(self); - let task_source = window.media_element_task_source(); + let task_source = window.task_manager().media_element_task_source(); task_source.queue_simple_event(self.upcast(), atom!("durationchange"), &window); } @@ -1147,7 +1150,7 @@ impl HTMLMediaElement { video_elem.set_video_width(metadata.width); video_elem.set_video_height(metadata.height); let window = window_from_node(self); - let task_source = window.media_element_task_source(); + let task_source = window.task_manager().media_element_task_source(); task_source.queue_simple_event(self.upcast(), atom!("resize"), &window); } } @@ -1515,11 +1518,10 @@ impl FetchResponseListener for HTMLMediaElementContext { // => "If mode is remote" step 2 if time::get_time() > self.next_progress_event { let window = window_from_node(&*elem); - window.media_element_task_source().queue_simple_event( - elem.upcast(), - atom!("progress"), - &window, - ); + window + .task_manager() + .media_element_task_source() + .queue_simple_event(elem.upcast(), atom!("progress"), &window); self.next_progress_event = time::get_time() + Duration::milliseconds(350); } } diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 47a4950b3d6d..d93b5357e241 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -25,7 +25,6 @@ use crate::dom::node::{document_from_node, window_from_node}; use crate::dom::node::{ChildrenMutation, CloneChildrenFlag, Node}; use crate::dom::virtualmethods::VirtualMethods; use crate::network_listener::{NetworkListener, PreInvoke}; -use crate::task_source::TaskSourceName; use dom_struct::dom_struct; use encoding_rs::Encoding; use html5ever::{LocalName, Prefix}; @@ -294,10 +293,14 @@ fn fetch_a_classic_script( })); let (action_sender, action_receiver) = ipc::channel().unwrap(); + let (task_source, canceller) = doc + .window() + .task_manager() + .networking_task_source_with_canceller(); let listener = NetworkListener { - context: context, - task_source: doc.window().networking_task_source(), - canceller: Some(doc.window().task_canceller(TaskSourceName::Networking)), + context, + task_source, + canceller: Some(canceller), }; ROUTER.add_route( @@ -623,11 +626,10 @@ impl HTMLScriptElement { pub fn queue_error_event(&self) { let window = window_from_node(self); - window.dom_manipulation_task_source().queue_simple_event( - self.upcast(), - atom!("error"), - &window, - ); + window + .task_manager() + .dom_manipulation_task_source() + .queue_simple_event(self.upcast(), atom!("error"), &window); } pub fn dispatch_load_event(&self) { diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs index 364640fa1699..4c9d12d560a2 100644 --- a/components/script/dom/htmlstyleelement.rs +++ b/components/script/dom/htmlstyleelement.rs @@ -127,11 +127,10 @@ impl HTMLStyleElement { // No subresource loads were triggered, queue load event if self.pending_loads.get() == 0 { let window = window_from_node(self); - window.dom_manipulation_task_source().queue_simple_event( - self.upcast(), - atom!("load"), - &window, - ); + window + .task_manager() + .dom_manipulation_task_source() + .queue_simple_event(self.upcast(), atom!("load"), &window); } self.set_stylesheet(sheet); diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index 89ffff3e030b..cb4929f4caba 100755 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -565,13 +565,16 @@ impl VirtualMethods for HTMLTextAreaElement { } else if event.type_() == atom!("keypress") && !event.DefaultPrevented() { if event.IsTrusted() { let window = window_from_node(self); - let _ = window.user_interaction_task_source().queue_event( - &self.upcast(), - atom!("input"), - EventBubbles::Bubbles, - EventCancelable::NotCancelable, - &window, - ); + let _ = window + .task_manager() + .user_interaction_task_source() + .queue_event( + &self.upcast(), + atom!("input"), + EventBubbles::Bubbles, + EventCancelable::NotCancelable, + &window, + ); } } } diff --git a/components/script/dom/offlineaudiocontext.rs b/components/script/dom/offlineaudiocontext.rs index f98f3b447504..dccc72427f8d 100644 --- a/components/script/dom/offlineaudiocontext.rs +++ b/components/script/dom/offlineaudiocontext.rs @@ -20,7 +20,7 @@ use crate::dom::event::{Event, EventBubbles, EventCancelable}; use crate::dom::offlineaudiocompletionevent::OfflineAudioCompletionEvent; use crate::dom::promise::Promise; use crate::dom::window::Window; -use crate::task_source::{TaskSource, TaskSourceName}; +use crate::task_source::TaskSource; use dom_struct::dom_struct; use servo_media::audio::context::OfflineAudioContextOptions as ServoMediaOfflineAudioContextOptions; use std::cell::Cell; @@ -141,8 +141,9 @@ impl OfflineAudioContextMethods for OfflineAudioContext { let this = Trusted::new(self); let global = self.global(); let window = global.as_window(); - let task_source = window.dom_manipulation_task_source(); - let canceller = window.task_canceller(TaskSourceName::DOMManipulation); + let (task_source, canceller) = window + .task_manager() + .dom_manipulation_task_source_with_canceller(); Builder::new() .name("OfflineAudioContextResolver".to_owned()) .spawn(move || { diff --git a/components/script/dom/storage.rs b/components/script/dom/storage.rs index ed6ed999fa24..4e8f08715719 100644 --- a/components/script/dom/storage.rs +++ b/components/script/dom/storage.rs @@ -209,6 +209,7 @@ impl Storage { let this = Trusted::new(self); global .as_window() + .task_manager() .dom_manipulation_task_source() .queue( task!(send_storage_notification: move || { diff --git a/components/script/dom/textcontrol.rs b/components/script/dom/textcontrol.rs index 3ed20a2901a1..1f276b94ba8e 100644 --- a/components/script/dom/textcontrol.rs +++ b/components/script/dom/textcontrol.rs @@ -297,13 +297,16 @@ impl<'a, E: TextControlElement> TextControlSelection<'a, E> { // Step 6 if textinput.selection_state() != original_selection_state { let window = window_from_node(self.element); - window.user_interaction_task_source().queue_event( - &self.element.upcast::(), - atom!("select"), - EventBubbles::Bubbles, - EventCancelable::NotCancelable, - &window, - ); + window + .task_manager() + .user_interaction_task_source() + .queue_event( + &self.element.upcast::(), + atom!("select"), + EventBubbles::Bubbles, + EventCancelable::NotCancelable, + &window, + ); } self.element diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 110356374f6d..51c379145c22 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -64,16 +64,7 @@ use crate::script_runtime::{ }; use crate::script_thread::{ImageCacheMsg, MainThreadScriptChan, MainThreadScriptMsg}; use crate::script_thread::{ScriptThread, SendableMainThreadScriptChan}; -use crate::task::TaskCanceller; -use crate::task_source::dom_manipulation::DOMManipulationTaskSource; -use crate::task_source::file_reading::FileReadingTaskSource; -use crate::task_source::history_traversal::HistoryTraversalTaskSource; -use crate::task_source::media_element::MediaElementTaskSource; -use crate::task_source::networking::NetworkingTaskSource; -use crate::task_source::performance_timeline::PerformanceTimelineTaskSource; -use crate::task_source::remote_event::RemoteEventTaskSource; -use crate::task_source::user_interaction::UserInteractionTaskSource; -use crate::task_source::websocket::WebsocketTaskSource; +use crate::task_manager::TaskManager; use crate::task_source::TaskSourceName; use crate::timers::{IsInterval, TimerCallback}; use crate::webdriver_handlers::jsval_to_webdriver; @@ -127,7 +118,7 @@ use std::fs; use std::io::{stderr, stdout, Write}; use std::mem; use std::rc::Rc; -use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::atomic::Ordering; use std::sync::{Arc, Mutex}; use style::error_reporting::ParseErrorReporter; use style::media_queries; @@ -180,24 +171,7 @@ pub struct Window { globalscope: GlobalScope, #[ignore_malloc_size_of = "trait objects are hard"] script_chan: MainThreadScriptChan, - #[ignore_malloc_size_of = "task sources are hard"] - dom_manipulation_task_source: DOMManipulationTaskSource, - #[ignore_malloc_size_of = "task sources are hard"] - media_element_task_source: MediaElementTaskSource, - #[ignore_malloc_size_of = "task sources are hard"] - user_interaction_task_source: UserInteractionTaskSource, - #[ignore_malloc_size_of = "task sources are hard"] - networking_task_source: NetworkingTaskSource, - #[ignore_malloc_size_of = "task sources are hard"] - history_traversal_task_source: HistoryTraversalTaskSource, - #[ignore_malloc_size_of = "task sources are hard"] - file_reading_task_source: FileReadingTaskSource, - #[ignore_malloc_size_of = "task sources are hard"] - performance_timeline_task_source: PerformanceTimelineTaskSource, - #[ignore_malloc_size_of = "task sources are hard"] - remote_event_task_source: RemoteEventTaskSource, - #[ignore_malloc_size_of = "task sources are hard"] - websocket_task_source: WebsocketTaskSource, + task_manager: TaskManager, navigator: MutNullableDom, #[ignore_malloc_size_of = "Arc"] image_cache: Arc, @@ -273,10 +247,6 @@ pub struct Window { current_viewport: Cell>, - /// A map of flags to prevent events from a given task source from attempting to interact with this window. - #[ignore_malloc_size_of = "defined in std"] - ignore_further_async_events: DomRefCell>>, - error_reporter: CSSErrorReporter, /// A list of scroll offsets for each scrollable element. @@ -324,6 +294,10 @@ pub struct Window { } impl Window { + pub fn task_manager(&self) -> &TaskManager { + &self.task_manager + } + pub fn get_exists_mut_observer(&self) -> bool { self.exists_mut_observer.get() } @@ -343,7 +317,7 @@ impl Window { } fn ignore_all_events(&self) { - let mut ignore_flags = self.ignore_further_async_events.borrow_mut(); + let mut ignore_flags = self.task_manager.task_cancellers.borrow_mut(); for task_source_name in TaskSourceName::all() { let flag = ignore_flags .entry(task_source_name) @@ -365,39 +339,6 @@ impl Window { self.js_runtime.borrow().as_ref().unwrap().cx() } - pub fn dom_manipulation_task_source(&self) -> DOMManipulationTaskSource { - self.dom_manipulation_task_source.clone() - } - - pub fn media_element_task_source(&self) -> MediaElementTaskSource { - self.media_element_task_source.clone() - } - - pub fn user_interaction_task_source(&self) -> UserInteractionTaskSource { - self.user_interaction_task_source.clone() - } - - pub fn networking_task_source(&self) -> NetworkingTaskSource { - self.networking_task_source.clone() - } - - pub fn file_reading_task_source(&self) -> TaskManagement { - let canceller = self.task_canceller(TaskSourceName::FileReading); - TaskManagement(self.file_reading_task_source.clone(), canceller) - } - - pub fn performance_timeline_task_source(&self) -> PerformanceTimelineTaskSource { - self.performance_timeline_task_source.clone() - } - - pub fn remote_event_task_source(&self) -> RemoteEventTaskSource { - self.remote_event_task_source.clone() - } - - pub fn websocket_task_source(&self) -> WebsocketTaskSource { - self.websocket_task_source.clone() - } - pub fn main_thread_script_chan(&self) -> &Sender { &self.script_chan.0 } @@ -1231,14 +1172,6 @@ impl Window { self.paint_worklet.or_init(|| self.new_paint_worklet()) } - pub fn task_canceller(&self, name: TaskSourceName) -> TaskCanceller { - let mut flags = self.ignore_further_async_events.borrow_mut(); - let cancel_flag = flags.entry(name).or_insert(Default::default()); - TaskCanceller { - cancelled: Some(cancel_flag.clone()), - } - } - pub fn get_navigation_start(&self) -> u64 { self.navigation_start_precise.get() } @@ -1249,10 +1182,10 @@ impl Window { /// Cancels all the tasks associated with that window. /// - /// This sets the current `ignore_further_async_events` sentinel value to + /// This sets the current `task_manager.task_cancellers` sentinel value to /// `true` and replaces it with a brand new one for future tasks. pub fn cancel_all_tasks(&self) { - let mut ignore_flags = self.ignore_further_async_events.borrow_mut(); + let mut ignore_flags = self.task_manager.task_cancellers.borrow_mut(); for task_source_name in TaskSourceName::all() { let flag = ignore_flags .entry(task_source_name) @@ -1266,7 +1199,7 @@ impl Window { /// This sets the current sentinel value to /// `true` and replaces it with a brand new one for future tasks. pub fn cancel_all_tasks_from_source(&self, task_source_name: TaskSourceName) { - let mut ignore_flags = self.ignore_further_async_events.borrow_mut(); + let mut ignore_flags = self.task_manager.task_cancellers.borrow_mut(); let flag = ignore_flags .entry(task_source_name) .or_insert(Default::default()); @@ -1827,7 +1760,8 @@ impl Window { let _ = self.script_chan.send(CommonScriptMsg::Task( ScriptThreadEventCategory::DomEvent, Box::new( - self.task_canceller(TaskSourceName::DOMManipulation) + self.task_manager + .task_canceller(TaskSourceName::DOMManipulation) .wrap_task(task), ), self.pipeline_id(), @@ -2073,15 +2007,7 @@ impl Window { pub fn new( runtime: Rc, script_chan: MainThreadScriptChan, - dom_manipulation_task_source: DOMManipulationTaskSource, - media_element_task_source: MediaElementTaskSource, - user_interaction_task_source: UserInteractionTaskSource, - networking_task_source: NetworkingTaskSource, - history_traversal_task_source: HistoryTraversalTaskSource, - file_reading_task_source: FileReadingTaskSource, - performance_timeline_task_source: PerformanceTimelineTaskSource, - remote_event_task_source: RemoteEventTaskSource, - websocket_task_source: WebsocketTaskSource, + task_manager: TaskManager, image_cache_chan: Sender, image_cache: Arc, resource_threads: ResourceThreads, @@ -2129,15 +2055,7 @@ impl Window { microtask_queue, ), script_chan, - dom_manipulation_task_source, - media_element_task_source, - user_interaction_task_source, - networking_task_source, - history_traversal_task_source, - file_reading_task_source, - performance_timeline_task_source, - remote_event_task_source, - websocket_task_source, + task_manager, image_cache_chan, image_cache, navigator: Default::default(), @@ -2170,7 +2088,6 @@ impl Window { devtools_marker_sender: Default::default(), devtools_markers: Default::default(), webdriver_script_chan: Default::default(), - ignore_further_async_events: Default::default(), error_reporter, scroll_offsets: Default::default(), media_query_lists: DOMTracker::new(), @@ -2311,7 +2228,8 @@ impl Window { let _ = self.script_chan.send(CommonScriptMsg::Task( ScriptThreadEventCategory::DomEvent, Box::new( - self.task_canceller(TaskSourceName::DOMManipulation) + self.task_manager + .task_canceller(TaskSourceName::DOMManipulation) .wrap_task(task), ), self.pipeline_id(), diff --git a/components/script/layout_image.rs b/components/script/layout_image.rs index 68a3e788cf4e..39670eefabb8 100644 --- a/components/script/layout_image.rs +++ b/components/script/layout_image.rs @@ -10,7 +10,6 @@ use crate::dom::bindings::reflector::DomObject; use crate::dom::node::{document_from_node, Node}; use crate::network_listener::{NetworkListener, PreInvoke}; -use crate::task_source::TaskSourceName; use ipc_channel::ipc; use ipc_channel::router::ROUTER; use net_traits::image_cache::{ImageCache, PendingImageId}; @@ -57,13 +56,16 @@ pub fn fetch_image_for_layout( })); let document = document_from_node(node); - let window = document.window(); let (action_sender, action_receiver) = ipc::channel().unwrap(); + let (task_source, canceller) = document + .window() + .task_manager() + .networking_task_source_with_canceller(); let listener = NetworkListener { - context: context, - task_source: window.networking_task_source(), - canceller: Some(window.task_canceller(TaskSourceName::Networking)), + context, + task_source, + canceller: Some(canceller), }; ROUTER.add_route( action_receiver.to_opaque(), diff --git a/components/script/lib.rs b/components/script/lib.rs index 1e4579597a63..8d591886a52e 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -69,6 +69,7 @@ pub mod script_thread; mod serviceworker_manager; mod serviceworkerjob; mod stylesheet_loader; +mod task_manager; mod task_queue; mod task_source; pub mod test; diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index c4177500b642..fe102a0a7b33 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -70,6 +70,7 @@ use crate::microtask::{Microtask, MicrotaskQueue}; use crate::script_runtime::{get_reports, new_rt_and_cx, Runtime, ScriptPort}; use crate::script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCategory}; use crate::serviceworkerjob::{Job, JobQueue}; +use crate::task_manager::TaskManager; use crate::task_queue::{QueuedTask, QueuedTaskConversion, TaskQueue}; use crate::task_source::dom_manipulation::DOMManipulationTaskSource; use crate::task_source::file_reading::FileReadingTaskSource; @@ -2583,20 +2584,23 @@ impl ScriptThread { pipeline_id: incomplete.pipeline_id, }; - // Create the window and document objects. - let window = Window::new( - self.js_runtime.clone(), - MainThreadScriptChan(sender.clone()), + let task_manager = TaskManager::new( self.dom_manipulation_task_source(incomplete.pipeline_id), + self.file_reading_task_source(incomplete.pipeline_id), + self.history_traversal_task_source(incomplete.pipeline_id), self.media_element_task_source(incomplete.pipeline_id), - self.user_interaction_task_source(incomplete.pipeline_id), self.networking_task_source(incomplete.pipeline_id), - self.history_traversal_task_source(incomplete.pipeline_id), - self.file_reading_task_source(incomplete.pipeline_id), self.performance_timeline_task_source(incomplete.pipeline_id) .clone(), + self.user_interaction_task_source(incomplete.pipeline_id), self.remote_event_task_source(incomplete.pipeline_id), self.websocket_task_source(incomplete.pipeline_id), + ); + // Create the window and document objects. + let window = Window::new( + self.js_runtime.clone(), + MainThreadScriptChan(sender.clone()), + task_manager, self.image_cache_channel.clone(), self.image_cache.clone(), self.resource_threads.clone(), diff --git a/components/script/stylesheet_loader.rs b/components/script/stylesheet_loader.rs index 29144d488368..43d9cb3bb928 100644 --- a/components/script/stylesheet_loader.rs +++ b/components/script/stylesheet_loader.rs @@ -13,7 +13,6 @@ use crate::dom::htmlelement::HTMLElement; use crate::dom::htmllinkelement::{HTMLLinkElement, RequestGenerationId}; use crate::dom::node::{document_from_node, window_from_node}; use crate::network_listener::{NetworkListener, PreInvoke}; -use crate::task_source::TaskSourceName; use cssparser::SourceLocation; use encoding_rs::UTF_8; use ipc_channel::ipc; @@ -245,10 +244,14 @@ impl<'a> StylesheetLoader<'a> { })); let (action_sender, action_receiver) = ipc::channel().unwrap(); + let (task_source, canceller) = document + .window() + .task_manager() + .networking_task_source_with_canceller(); let listener = NetworkListener { - context: context, - task_source: document.window().networking_task_source(), - canceller: Some(document.window().task_canceller(TaskSourceName::Networking)), + context, + task_source, + canceller: Some(canceller), }; ROUTER.add_route( action_receiver.to_opaque(), diff --git a/components/script/task_manager.rs b/components/script/task_manager.rs new file mode 100644 index 000000000000..90110913e5fc --- /dev/null +++ b/components/script/task_manager.rs @@ -0,0 +1,162 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use crate::dom::bindings::cell::DomRefCell; +use crate::task::TaskCanceller; +use crate::task_source::dom_manipulation::DOMManipulationTaskSource; +use crate::task_source::file_reading::FileReadingTaskSource; +use crate::task_source::history_traversal::HistoryTraversalTaskSource; +use crate::task_source::media_element::MediaElementTaskSource; +use crate::task_source::networking::NetworkingTaskSource; +use crate::task_source::performance_timeline::PerformanceTimelineTaskSource; +use crate::task_source::remote_event::RemoteEventTaskSource; +use crate::task_source::user_interaction::UserInteractionTaskSource; +use crate::task_source::websocket::WebsocketTaskSource; +use crate::task_source::TaskSourceName; +use std::collections::HashMap; +use std::sync::atomic::AtomicBool; +use std::sync::Arc; + +macro_rules! task_source_functions { + ($self:ident,$with_canceller:ident,$task_source:ident,$task_source_type:ident,$task_source_name:ident) => { + pub fn $with_canceller(&$self) -> ($task_source_type, TaskCanceller) { + ($self.$task_source.clone(), $self.task_canceller(TaskSourceName::$task_source_name)) + } + + pub fn $task_source(&$self) -> $task_source_type { + $self.$task_source.clone() + } + } +} + +#[derive(JSTraceable, MallocSizeOf)] +pub struct TaskManager { + #[ignore_malloc_size_of = "task sources are hard"] + pub task_cancellers: DomRefCell>>, + #[ignore_malloc_size_of = "task sources are hard"] + dom_manipulation_task_source: DOMManipulationTaskSource, + #[ignore_malloc_size_of = "task sources are hard"] + file_reading_task_source: FileReadingTaskSource, + #[ignore_malloc_size_of = "task sources are hard"] + history_traversal_task_source: HistoryTraversalTaskSource, + #[ignore_malloc_size_of = "task sources are hard"] + media_element_task_source: MediaElementTaskSource, + #[ignore_malloc_size_of = "task sources are hard"] + networking_task_source: NetworkingTaskSource, + #[ignore_malloc_size_of = "task sources are hard"] + performance_timeline_task_source: PerformanceTimelineTaskSource, + #[ignore_malloc_size_of = "task sources are hard"] + user_interaction_task_source: UserInteractionTaskSource, + #[ignore_malloc_size_of = "task sources are hard"] + remote_event_task_source: RemoteEventTaskSource, + #[ignore_malloc_size_of = "task sources are hard"] + websocket_task_source: WebsocketTaskSource, +} + +impl TaskManager { + pub fn new( + dom_manipulation_task_source: DOMManipulationTaskSource, + file_reading_task_source: FileReadingTaskSource, + history_traversal_task_source: HistoryTraversalTaskSource, + media_element_task_source: MediaElementTaskSource, + networking_task_source: NetworkingTaskSource, + performance_timeline_task_source: PerformanceTimelineTaskSource, + user_interaction_task_source: UserInteractionTaskSource, + remote_event_task_source: RemoteEventTaskSource, + websocket_task_source: WebsocketTaskSource, + ) -> Self { + TaskManager { + dom_manipulation_task_source, + file_reading_task_source, + history_traversal_task_source, + media_element_task_source, + networking_task_source, + performance_timeline_task_source, + user_interaction_task_source, + remote_event_task_source, + websocket_task_source, + task_cancellers: Default::default(), + } + } + + task_source_functions!( + self, + dom_manipulation_task_source_with_canceller, + dom_manipulation_task_source, + DOMManipulationTaskSource, + DOMManipulation + ); + + task_source_functions!( + self, + media_element_task_source_with_canceller, + media_element_task_source, + MediaElementTaskSource, + MediaElement + ); + + task_source_functions!( + self, + user_interaction_task_source_with_canceller, + user_interaction_task_source, + UserInteractionTaskSource, + UserInteraction + ); + + task_source_functions!( + self, + networking_task_source_with_canceller, + networking_task_source, + NetworkingTaskSource, + Networking + ); + + task_source_functions!( + self, + file_reading_task_source_with_canceller, + file_reading_task_source, + FileReadingTaskSource, + FileReading + ); + + task_source_functions!( + self, + history_traversal_task_source_with_canceller, + history_traversal_task_source, + HistoryTraversalTaskSource, + HistoryTraversal + ); + + task_source_functions!( + self, + performance_timeline_task_source_with_canceller, + performance_timeline_task_source, + PerformanceTimelineTaskSource, + PerformanceTimeline + ); + + task_source_functions!( + self, + remote_event_task_source_with_canceller, + remote_event_task_source, + RemoteEventTaskSource, + RemoteEvent + ); + + task_source_functions!( + self, + websocket_task_source_with_canceller, + websocket_task_source, + WebsocketTaskSource, + Websocket + ); + + pub fn task_canceller(&self, name: TaskSourceName) -> TaskCanceller { + let mut flags = self.task_cancellers.borrow_mut(); + let cancel_flag = flags.entry(name).or_insert(Default::default()); + TaskCanceller { + cancelled: Some(cancel_flag.clone()), + } + } +} diff --git a/components/script/task_source/history_traversal.rs b/components/script/task_source/history_traversal.rs index ee73e7e991e7..aa6877c93793 100644 --- a/components/script/task_source/history_traversal.rs +++ b/components/script/task_source/history_traversal.rs @@ -2,28 +2,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use crate::script_runtime::{CommonScriptMsg, ScriptThreadEventCategory}; +use crate::script_thread::MainThreadScriptMsg; +use crate::task::{TaskCanceller, TaskOnce}; +use crate::task_source::{TaskSource, TaskSourceName}; use msg::constellation_msg::PipelineId; -use script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCategory}; -use script_thread::MainThreadScriptMsg; use servo_channel::Sender; -use task::{TaskCanceller, TaskOnce}; -use task_source::{TaskSource, TaskSourceName}; -#[derive(JSTraceable)] +#[derive(Clone, JSTraceable)] pub struct HistoryTraversalTaskSource(pub Sender, pub PipelineId); -impl ScriptChan for HistoryTraversalTaskSource { - fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> { - self.0 - .send(MainThreadScriptMsg::Common(msg)) - .map_err(|_| ()) - } - - fn clone(&self) -> Box { - Box::new(HistoryTraversalTaskSource((&self.0).clone(), (&self.1).clone())) - } -} - impl TaskSource for HistoryTraversalTaskSource { const NAME: TaskSourceName = TaskSourceName::HistoryTraversal;