From 3875b3dac8d20f9843723b5e8cf964ad0182eaa9 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Wed, 20 Sep 2017 05:17:12 -0500 Subject: [PATCH] servo: Merge #18573 - Introduce TaskOnce (from servo:TASKS); r=SimonSapin Source-Repo: https://github.com/servo/servo Source-Revision: 44c6bd9fa9594e7fd2a6576a4eab501a5838d113 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 8814df2f1a210ddeba69a81774f35853fcc018fd --- .../script/dom/bindings/refcounted.rs | 6 +- servo/components/script/dom/bluetooth.rs | 13 ++--- servo/components/script/dom/document.rs | 2 +- servo/components/script/dom/element.rs | 10 ++-- servo/components/script/dom/event.rs | 10 ++-- servo/components/script/dom/eventsource.rs | 8 +-- servo/components/script/dom/filereader.rs | 6 +- .../script/dom/htmldetailselement.rs | 2 +- .../components/script/dom/htmlformelement.rs | 2 +- .../script/dom/htmliframeelement.rs | 2 +- .../components/script/dom/htmlimageelement.rs | 10 ++-- .../components/script/dom/htmlmediaelement.rs | 6 +- servo/components/script/dom/serviceworker.rs | 9 ++- servo/components/script/dom/storage.rs | 2 +- servo/components/script/dom/websocket.rs | 26 ++++----- servo/components/script/dom/window.rs | 4 +- servo/components/script/dom/worker.rs | 9 ++- .../script/dom/workerglobalscope.rs | 2 +- servo/components/script/dom/worklet.rs | 7 ++- servo/components/script/network_listener.rs | 13 ++--- servo/components/script/script_runtime.rs | 4 +- servo/components/script/script_thread.rs | 2 +- servo/components/script/serviceworkerjob.rs | 2 +- servo/components/script/task.rs | 57 +++++++++++++------ .../script/task_source/dom_manipulation.rs | 12 ++-- .../script/task_source/file_reading.rs | 12 ++-- servo/components/script/task_source/mod.rs | 13 +++-- .../script/task_source/networking.rs | 17 +++--- .../task_source/performance_timeline.rs | 10 ++-- .../script/task_source/user_interaction.rs | 10 ++-- 30 files changed, 157 insertions(+), 131 deletions(-) diff --git a/servo/components/script/dom/bindings/refcounted.rs b/servo/components/script/dom/bindings/refcounted.rs index cdf80264edb5..45d7d7213077 100644 --- a/servo/components/script/dom/bindings/refcounted.rs +++ b/servo/components/script/dom/bindings/refcounted.rs @@ -40,7 +40,7 @@ use std::marker::PhantomData; use std::os; use std::rc::Rc; use std::sync::{Arc, Weak}; -use task::Task; +use task::TaskOnce; #[allow(missing_docs)] // FIXME @@ -122,7 +122,7 @@ impl TrustedPromise { /// A task which will reject the promise. #[allow(unrooted_must_root)] - pub fn reject_task(self, error: Error) -> impl Send + Task { + pub fn reject_task(self, error: Error) -> impl TaskOnce { let this = self; task!(reject_promise: move || { debug!("Rejecting promise."); @@ -135,7 +135,7 @@ impl TrustedPromise { /// A task which will resolve the promise. #[allow(unrooted_must_root)] - pub fn resolve_task(self, value: T) -> impl Send + Task + pub fn resolve_task(self, value: T) -> impl TaskOnce where T: ToJSValConvertible + Send, { diff --git a/servo/components/script/dom/bluetooth.rs b/servo/components/script/dom/bluetooth.rs index 2cd557d52b8d..526ebe576fc4 100644 --- a/servo/components/script/dom/bluetooth.rs +++ b/servo/components/script/dom/bluetooth.rs @@ -40,7 +40,7 @@ use std::collections::HashMap; use std::rc::Rc; use std::str::FromStr; use std::sync::{Arc, Mutex}; -use task::Task; +use task::TaskOnce; const KEY_CONVERSION_ERROR: &'static str = "This `manufacturerData` key can not be parsed as unsigned short:"; const FILTER_EMPTY_ERROR: &'static str = "'filters' member, if present, must be nonempty to find any devices."; @@ -229,18 +229,17 @@ pub fn response_async( action: BluetoothResponseResult, } - impl Task for ListenerTask + impl TaskOnce for ListenerTask where T: AsyncBluetoothListener + DomObject, { - fn run(self: Box) { - let this = *self; - let mut context = this.context.lock().unwrap(); - context.response(this.action); + fn run_once(self) { + let mut context = self.context.lock().unwrap(); + context.response(self.action); } } - let task = box ListenerTask { + let task = ListenerTask { context: context.clone(), action: message.to().unwrap(), }; diff --git a/servo/components/script/dom/document.rs b/servo/components/script/dom/document.rs index 0d180ca99348..e3bb46bf5c03 100644 --- a/servo/components/script/dom/document.rs +++ b/servo/components/script/dom/document.rs @@ -1716,7 +1716,7 @@ impl Document { debug!("Document loads are complete."); let document = Trusted::new(self); self.window.dom_manipulation_task_source().queue( - box task!(fire_load_event: move || { + task!(fire_load_event: move || { let document = document.root(); let window = document.window(); if !window.is_alive() { diff --git a/servo/components/script/dom/element.rs b/servo/components/script/dom/element.rs index c0524cf308c7..195884bebab8 100644 --- a/servo/components/script/dom/element.rs +++ b/servo/components/script/dom/element.rs @@ -119,7 +119,7 @@ use style::thread_state; use style::values::{CSSFloat, Either}; use style::values::{specified, computed}; use stylesheet_loader::StylesheetOwner; -use task::Task; +use task::TaskOnce; // TODO: Update focus state when the top-level browsing context gains or loses system focus, // and when the element enters or leaves a browsing context container. @@ -3047,9 +3047,9 @@ impl ElementPerformFullscreenEnter { } } -impl Task for ElementPerformFullscreenEnter { +impl TaskOnce for ElementPerformFullscreenEnter { #[allow(unrooted_must_root)] - fn run(self: Box) { + fn run_once(self) { let element = self.element.root(); let document = document_from_node(element.r()); @@ -3100,9 +3100,9 @@ impl ElementPerformFullscreenExit { } } -impl Task for ElementPerformFullscreenExit { +impl TaskOnce for ElementPerformFullscreenExit { #[allow(unrooted_must_root)] - fn run(self: Box) { + fn run_once(self) { let element = self.element.root(); let document = document_from_node(element.r()); // TODO Step 9.1-5 diff --git a/servo/components/script/dom/event.rs b/servo/components/script/dom/event.rs index f5143ec72c41..c9ef22bc6c10 100644 --- a/servo/components/script/dom/event.rs +++ b/servo/components/script/dom/event.rs @@ -23,7 +23,7 @@ use dom_struct::dom_struct; use servo_atoms::Atom; use std::cell::Cell; use std::default::Default; -use task::Task; +use task::TaskOnce; use time; #[dom_struct] @@ -388,8 +388,8 @@ pub struct EventTask { pub cancelable: EventCancelable, } -impl Task for EventTask { - fn run(self: Box) { +impl TaskOnce for EventTask { + fn run_once(self) { let target = self.target.root(); let bubbles = self.bubbles; let cancelable = self.cancelable; @@ -403,8 +403,8 @@ pub struct SimpleEventTask { pub name: Atom, } -impl Task for SimpleEventTask { - fn run(self: Box) { +impl TaskOnce for SimpleEventTask { + fn run_once(self) { let target = self.target.root(); target.fire_event(self.name); } diff --git a/servo/components/script/dom/eventsource.rs b/servo/components/script/dom/eventsource.rs index bf4c1c78c954..07f5c3b45008 100644 --- a/servo/components/script/dom/eventsource.rs +++ b/servo/components/script/dom/eventsource.rs @@ -100,7 +100,7 @@ impl EventSourceContext { let event_source = self.event_source.clone(); // FIXME(nox): Why are errors silenced here? let _ = global.networking_task_source().queue( - box task!(announce_the_event_source_connection: move || { + task!(announce_the_event_source_connection: move || { let event_source = event_source.root(); if event_source.ready_state.get() != ReadyState::Closed { event_source.ready_state.set(ReadyState::Open); @@ -121,7 +121,7 @@ impl EventSourceContext { let event_source = self.event_source.clone(); // FIXME(nox): Why are errors silenced here? let _ = global.networking_task_source().queue( - box task!(fail_the_event_source_connection: move || { + task!(fail_the_event_source_connection: move || { let event_source = event_source.root(); if event_source.ready_state.get() != ReadyState::Closed { event_source.ready_state.set(ReadyState::Closed); @@ -145,7 +145,7 @@ impl EventSourceContext { let global = event_source.global(); // FIXME(nox): Why are errors silenced here? let _ = global.networking_task_source().queue( - box task!(reestablish_the_event_source_onnection: move || { + task!(reestablish_the_event_source_onnection: move || { let event_source = trusted_event_source.root(); // Step 1.1. @@ -242,7 +242,7 @@ impl EventSourceContext { let event = Trusted::new(&*event); // FIXME(nox): Why are errors silenced here? let _ = global.networking_task_source().queue( - box task!(dispatch_the_event_source_event: move || { + task!(dispatch_the_event_source_event: move || { let event_source = event_source.root(); if event_source.ready_state.get() != ReadyState::Closed { event.root().upcast::().fire(&event_source.upcast()); diff --git a/servo/components/script/dom/filereader.rs b/servo/components/script/dom/filereader.rs index b2f5b1ca36f7..3ee3c146b751 100644 --- a/servo/components/script/dom/filereader.rs +++ b/servo/components/script/dom/filereader.rs @@ -416,11 +416,11 @@ fn perform_annotated_read_operation( ) { // Step 4 let task = FileReadingTask::ProcessRead(filereader.clone(), gen_id); - task_source.queue_with_canceller(box task, &canceller).unwrap(); + task_source.queue_with_canceller(task, &canceller).unwrap(); let task = FileReadingTask::ProcessReadData(filereader.clone(), gen_id); - task_source.queue_with_canceller(box task, &canceller).unwrap(); + task_source.queue_with_canceller(task, &canceller).unwrap(); let task = FileReadingTask::ProcessReadEOF(filereader, gen_id, data, blob_contents); - task_source.queue_with_canceller(box task, &canceller).unwrap(); + task_source.queue_with_canceller(task, &canceller).unwrap(); } diff --git a/servo/components/script/dom/htmldetailselement.rs b/servo/components/script/dom/htmldetailselement.rs index 59090f80f48f..72952da8310c 100644 --- a/servo/components/script/dom/htmldetailselement.rs +++ b/servo/components/script/dom/htmldetailselement.rs @@ -70,7 +70,7 @@ impl VirtualMethods for HTMLDetailsElement { let this = Trusted::new(self); // FIXME(nox): Why are errors silenced here? let _ = window.dom_manipulation_task_source().queue( - box task!(details_notification_task_steps: move || { + task!(details_notification_task_steps: move || { let this = this.root(); if counter == this.toggle_counter.get() { this.upcast::().fire_event(atom!("toggle")); diff --git a/servo/components/script/dom/htmlformelement.rs b/servo/components/script/dom/htmlformelement.rs index 81b9cdb44a12..f396bc51715a 100755 --- a/servo/components/script/dom/htmlformelement.rs +++ b/servo/components/script/dom/htmlformelement.rs @@ -440,7 +440,7 @@ impl HTMLFormElement { let pipeline_id = window.upcast::().pipeline_id(); let script_chan = window.main_thread_script_chan().clone(); let this = Trusted::new(self); - let task = box task!(navigate_to_form_planned_navigation: move || { + let task = task!(navigate_to_form_planned_navigation: move || { if generation_id != this.root().generation_id.get() { return; } diff --git a/servo/components/script/dom/htmliframeelement.rs b/servo/components/script/dom/htmliframeelement.rs index 81a0f8417a74..7f0b82fa2391 100644 --- a/servo/components/script/dom/htmliframeelement.rs +++ b/servo/components/script/dom/htmliframeelement.rs @@ -236,7 +236,7 @@ impl HTMLIFrameElement { let pipeline_id = self.pipeline_id().unwrap(); // FIXME(nox): Why are errors silenced here? let _ = window.dom_manipulation_task_source().queue( - box task!(iframe_load_event_steps: move || { + task!(iframe_load_event_steps: move || { this.root().iframe_load_event_steps(pipeline_id); }), window.upcast(), diff --git a/servo/components/script/dom/htmlimageelement.rs b/servo/components/script/dom/htmlimageelement.rs index 30ef64da97e6..49db07a3242c 100644 --- a/servo/components/script/dom/htmlimageelement.rs +++ b/servo/components/script/dom/htmlimageelement.rs @@ -174,7 +174,7 @@ impl HTMLImageElement { let image = message.to().unwrap(); // FIXME(nox): Why are errors silenced here? let _ = task_source.queue_with_canceller( - box task!(process_image_response: move || { + task!(process_image_response: move || { let element = element.root(); // Ignore any image response for a previous request that has been discarded. if generation == element.generation.get() { @@ -425,7 +425,7 @@ impl HTMLImageElement { // Step 9. // FIXME(nox): Why are errors silenced here? let _ = task_source.queue( - box task!(image_null_source_error: move || { + task!(image_null_source_error: move || { let this = this.root(); { let mut current_request = @@ -451,7 +451,7 @@ impl HTMLImageElement { let target = Trusted::new(self.upcast::()); // FIXME(nox): Why are errors silenced here? let _ = task_source.queue( - box task!(fire_progress_event: move || { + task!(fire_progress_event: move || { let target = target.root(); let event = ProgressEvent::new( @@ -480,7 +480,7 @@ impl HTMLImageElement { let src = String::from(src); // FIXME(nox): Why are errors silenced here? let _ = task_source.queue( - box task!(image_selected_source_error: move || { + task!(image_selected_source_error: move || { let this = this.root(); { let mut current_request = @@ -549,7 +549,7 @@ impl HTMLImageElement { let this = Trusted::new(self); let src = String::from(src); let _ = window.dom_manipulation_task_source().queue( - box task!(image_load_event: move || { + task!(image_load_event: move || { let this = this.root(); { let mut current_request = diff --git a/servo/components/script/dom/htmlmediaelement.rs b/servo/components/script/dom/htmlmediaelement.rs index 594c0ea221e3..3700a64364e7 100644 --- a/servo/components/script/dom/htmlmediaelement.rs +++ b/servo/components/script/dom/htmlmediaelement.rs @@ -154,7 +154,7 @@ impl HTMLMediaElement { let target = Trusted::new(self.upcast::()); // FIXME(nox): Why are errors silenced here? let _ = window.dom_manipulation_task_source().queue( - box task!(internal_pause_steps: move || { + task!(internal_pause_steps: move || { let target = target.root(); // Step 2.3.1. @@ -186,7 +186,7 @@ impl HTMLMediaElement { let window = window_from_node(self); // FIXME(nox): Why are errors silenced here? let _ = window.dom_manipulation_task_source().queue( - box task!(notify_about_playing: move || { + task!(notify_about_playing: move || { let target = target.root(); // Step 2.1. @@ -495,7 +495,7 @@ impl HTMLMediaElement { let window = window_from_node(self); // FIXME(nox): Why are errors silenced here? let _ = window.dom_manipulation_task_source().queue( - box task!(dedicated_media_source_failure_steps: move || { + task!(dedicated_media_source_failure_steps: move || { let this = this.root(); // Step 1. diff --git a/servo/components/script/dom/serviceworker.rs b/servo/components/script/dom/serviceworker.rs index 74169428453a..51c75309050b 100644 --- a/servo/components/script/dom/serviceworker.rs +++ b/servo/components/script/dom/serviceworker.rs @@ -19,7 +19,7 @@ use js::jsapi::{HandleValue, JSContext}; use script_traits::{ScriptMsg, DOMMessage}; use servo_url::ServoUrl; use std::cell::Cell; -use task::Task; +use task::TaskOnce; pub type TrustedServiceWorkerAddress = Trusted; @@ -104,10 +104,9 @@ impl ServiceWorkerMethods for ServiceWorker { event_handler!(statechange, GetOnstatechange, SetOnstatechange); } -impl Task for SimpleWorkerErrorHandler { +impl TaskOnce for SimpleWorkerErrorHandler { #[allow(unrooted_must_root)] - fn run(self: Box) { - let this = *self; - ServiceWorker::dispatch_simple_error(this.addr); + fn run_once(self) { + ServiceWorker::dispatch_simple_error(self.addr); } } diff --git a/servo/components/script/dom/storage.rs b/servo/components/script/dom/storage.rs index 3dbada1b3347..e7b948e46d6d 100644 --- a/servo/components/script/dom/storage.rs +++ b/servo/components/script/dom/storage.rs @@ -167,7 +167,7 @@ impl Storage { let global = self.global(); let this = Trusted::new(self); global.as_window().dom_manipulation_task_source().queue( - box task!(send_storage_notification: move || { + task!(send_storage_notification: move || { let this = this.root(); let global = this.global(); let event = StorageEvent::new( diff --git a/servo/components/script/dom/websocket.rs b/servo/components/script/dom/websocket.rs index 52b2dcc85d6f..3d482bb4fa56 100644 --- a/servo/components/script/dom/websocket.rs +++ b/servo/components/script/dom/websocket.rs @@ -37,7 +37,7 @@ use std::borrow::ToOwned; use std::cell::Cell; use std::ptr; use std::thread; -use task::{Task, TaskCanceller}; +use task::{TaskOnce, TaskCanceller}; use task_source::TaskSource; use task_source::networking::NetworkingTaskSource; @@ -74,7 +74,7 @@ pub fn close_the_websocket_connection( code: Option, reason: String, ) { - let close_task = box CloseTask { + let close_task = CloseTask { address: address, failed: false, code: code, @@ -88,7 +88,7 @@ pub fn fail_the_websocket_connection( task_source: &NetworkingTaskSource, canceller: &TaskCanceller, ) { - let close_task = box CloseTask { + let close_task = CloseTask { address: address, failed: true, code: Some(close_code::ABNORMAL), @@ -206,14 +206,14 @@ impl WebSocket { while let Ok(event) = dom_event_receiver.recv() { match event { WebSocketNetworkEvent::ConnectionEstablished { protocol_in_use } => { - let open_thread = box ConnectionEstablishedTask { + let open_thread = ConnectionEstablishedTask { address: address.clone(), protocol_in_use, }; task_source.queue_with_canceller(open_thread, &canceller).unwrap(); }, WebSocketNetworkEvent::MessageReceived(message) => { - let message_thread = box MessageReceivedTask { + let message_thread = MessageReceivedTask { address: address.clone(), message: message, }; @@ -397,9 +397,9 @@ struct ConnectionEstablishedTask { protocol_in_use: Option, } -impl Task for ConnectionEstablishedTask { +impl TaskOnce for ConnectionEstablishedTask { /// https://html.spec.whatwg.org/multipage/#feedback-from-the-protocol:concept-websocket-established - fn run(self: Box) { + fn run_once(self) { let ws = self.address.root(); // Step 1. @@ -422,13 +422,13 @@ struct BufferedAmountTask { address: Trusted, } -impl Task for BufferedAmountTask { +impl TaskOnce for BufferedAmountTask { // See https://html.spec.whatwg.org/multipage/#dom-websocket-bufferedamount // // To be compliant with standards, we need to reset bufferedAmount only when the event loop // reaches step 1. In our implementation, the bytes will already have been sent on a background // thread. - fn run(self: Box) { + fn run_once(self) { let ws = self.address.root(); ws.buffered_amount.set(0); @@ -443,8 +443,8 @@ struct CloseTask { reason: Option, } -impl Task for CloseTask { - fn run(self: Box) { +impl TaskOnce for CloseTask { + fn run_once(self) { let ws = self.address.root(); if ws.ready_state.get() == WebSocketRequestState::Closed { @@ -483,9 +483,9 @@ struct MessageReceivedTask { message: MessageData, } -impl Task for MessageReceivedTask { +impl TaskOnce for MessageReceivedTask { #[allow(unsafe_code)] - fn run(self: Box) { + fn run_once(self) { let ws = self.address.root(); debug!("MessageReceivedTask::handler({:p}): readyState={:?}", &*ws, ws.ready_state.get()); diff --git a/servo/components/script/dom/window.rs b/servo/components/script/dom/window.rs index c4a22c707575..1cb38d0a7cad 100644 --- a/servo/components/script/dom/window.rs +++ b/servo/components/script/dom/window.rs @@ -1977,7 +1977,7 @@ impl Window { serialize_with_transfer_result: StructuredCloneData, ) { let this = Trusted::new(self); - let task = box task!(post_serialised_message: move || { + let task = task!(post_serialised_message: move || { let this = this.root(); // Step 7.1. @@ -2012,7 +2012,7 @@ impl Window { // TODO(#12718): Use the "posted message task source". let _ = self.script_chan.send(CommonScriptMsg::Task( ScriptThreadEventCategory::DomEvent, - self.task_canceller().wrap_task(task), + box self.task_canceller().wrap_task(task), )); } } diff --git a/servo/components/script/dom/worker.rs b/servo/components/script/dom/worker.rs index d250633a49ed..7d9a3875f1b2 100644 --- a/servo/components/script/dom/worker.rs +++ b/servo/components/script/dom/worker.rs @@ -28,7 +28,7 @@ use std::cell::Cell; use std::sync::{Arc, Mutex}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::{Sender, channel}; -use task::Task; +use task::TaskOnce; pub type TrustedWorkerAddress = Trusted; @@ -175,10 +175,9 @@ impl WorkerMethods for Worker { event_handler!(error, GetOnerror, SetOnerror); } -impl Task for SimpleWorkerErrorHandler { +impl TaskOnce for SimpleWorkerErrorHandler { #[allow(unrooted_must_root)] - fn run(self: Box) { - let this = *self; - Worker::dispatch_simple_error(this.addr); + fn run_once(self) { + Worker::dispatch_simple_error(self.addr); } } diff --git a/servo/components/script/dom/workerglobalscope.rs b/servo/components/script/dom/workerglobalscope.rs index 57017f5cd55a..8ea1a49ccbec 100644 --- a/servo/components/script/dom/workerglobalscope.rs +++ b/servo/components/script/dom/workerglobalscope.rs @@ -388,7 +388,7 @@ impl WorkerGlobalScope { pub fn process_event(&self, msg: CommonScriptMsg) { match msg { CommonScriptMsg::Task(_, task) => { - task.run() + task.run_box() }, CommonScriptMsg::CollectReports(reports_chan) => { let cx = self.get_cx(); diff --git a/servo/components/script/dom/worklet.rs b/servo/components/script/dom/worklet.rs index b55f9d328a0a..4028670b3932 100644 --- a/servo/components/script/dom/worklet.rs +++ b/servo/components/script/dom/worklet.rs @@ -69,7 +69,7 @@ use std::thread; use style::thread_state; use swapper::Swapper; use swapper::swapper; -use task::Task; +use task::TaskBox; use uuid::Uuid; // Magic numbers @@ -645,8 +645,9 @@ impl WorkletThread { } /// Run a task in the main script thread. - fn run_in_script_thread(&self, task: T) where - T: 'static + Send + Task, + fn run_in_script_thread(&self, task: T) + where + T: TaskBox + 'static, { let msg = CommonScriptMsg::Task(ScriptThreadEventCategory::WorkletEvent, box task); let msg = MainThreadScriptMsg::Common(msg); diff --git a/servo/components/script/network_listener.rs b/servo/components/script/network_listener.rs index 8b2911280650..1e86f61dffec 100644 --- a/servo/components/script/network_listener.rs +++ b/servo/components/script/network_listener.rs @@ -4,7 +4,7 @@ use net_traits::{Action, FetchResponseListener, FetchResponseMsg}; use std::sync::{Arc, Mutex}; -use task::{Task, TaskCanceller}; +use task::{TaskCanceller, TaskOnce}; use task_source::TaskSource; use task_source::networking::NetworkingTaskSource; @@ -18,7 +18,7 @@ pub struct NetworkListener { impl NetworkListener { pub fn notify + Send + 'static>(&self, action: A) { - let task = box ListenerTask { + let task = ListenerTask { context: self.context.clone(), action: action, }; @@ -55,16 +55,15 @@ struct ListenerTask + Send + 'static, Listener: PreInvoke + action: A, } -impl Task for ListenerTask +impl TaskOnce for ListenerTask where A: Action + Send + 'static, Listener: PreInvoke + Send, { - fn run(self: Box) { - let this = *self; - let mut context = this.context.lock().unwrap(); + fn run_once(self) { + let mut context = self.context.lock().unwrap(); if context.should_invoke() { - this.action.process(&mut *context); + self.action.process(&mut *context); } } } diff --git a/servo/components/script/script_runtime.rs b/servo/components/script/script_runtime.rs index 270dd0cdafe2..be5acd33a6ac 100644 --- a/servo/components/script/script_runtime.rs +++ b/servo/components/script/script_runtime.rs @@ -35,7 +35,7 @@ use std::os::raw::c_void; use std::panic::AssertUnwindSafe; use std::ptr; use style::thread_state; -use task::Task; +use task::TaskBox; use time::{Tm, now}; /// Common messages used to control the event loops in both the script and the worker @@ -44,7 +44,7 @@ pub enum CommonScriptMsg { /// supplied channel. CollectReports(ReportsChan), /// Generic message that encapsulates event handling. - Task(ScriptThreadEventCategory, Box), + Task(ScriptThreadEventCategory, Box), } impl fmt::Debug for CommonScriptMsg { diff --git a/servo/components/script/script_thread.rs b/servo/components/script/script_thread.rs index 56f47cfdbefb..2fa0071ed659 100644 --- a/servo/components/script/script_thread.rs +++ b/servo/components/script/script_thread.rs @@ -1258,7 +1258,7 @@ impl ScriptThread { self.handle_exit_window_msg(id) }, MainThreadScriptMsg::Common(CommonScriptMsg::Task(_, task)) => { - task.run() + task.run_box() } MainThreadScriptMsg::Common(CommonScriptMsg::CollectReports(chan)) => { self.collect_reports(chan) diff --git a/servo/components/script/serviceworkerjob.rs b/servo/components/script/serviceworkerjob.rs index cae17fc65b1d..07d6c13ecfbd 100644 --- a/servo/components/script/serviceworkerjob.rs +++ b/servo/components/script/serviceworkerjob.rs @@ -275,7 +275,7 @@ fn queue_settle_promise_for_job(job: &Job, settle: SettleType, task_source: &DOM let promise = TrustedPromise::new(job.promise.clone()); // FIXME(nox): Why are errors silenced here? let _ = task_source.queue( - box task!(settle_promise_for_job: move || { + task!(settle_promise_for_job: move || { let promise = promise.root(); settle_job_promise(&promise.global(), &promise, settle) }), diff --git a/servo/components/script/task.rs b/servo/components/script/task.rs index 08f5c499aa6a..e90fc21c55cd 100644 --- a/servo/components/script/task.rs +++ b/servo/components/script/task.rs @@ -13,15 +13,15 @@ macro_rules! task { ($name:ident: move || $body:tt) => {{ #[allow(non_camel_case_types)] struct $name(F); - impl ::task::Task for $name + impl ::task::TaskOnce for $name where - F: ::std::ops::FnOnce(), + F: ::std::ops::FnOnce() + Send, { fn name(&self) -> &'static str { stringify!($name) } - fn run(self: Box) { + fn run_once(self) { (self.0)(); } } @@ -30,13 +30,36 @@ macro_rules! task { } /// A task that can be run. The name method is for profiling purposes. -pub trait Task { +pub trait TaskOnce: Send { #[allow(unsafe_code)] - fn name(&self) -> &'static str { unsafe { intrinsics::type_name::() } } - fn run(self: Box); + fn name(&self) -> &'static str { + unsafe { intrinsics::type_name::() } + } + + fn run_once(self); } -impl fmt::Debug for Task + Send { +/// A boxed version of `TaskOnce`. +pub trait TaskBox: Send { + fn name(&self) -> &'static str; + + fn run_box(self: Box); +} + +impl TaskBox for T +where + T: TaskOnce, +{ + fn name(&self) -> &'static str { + TaskOnce::name(self) + } + + fn run_box(self: Box) { + self.run_once() + } +} + +impl fmt::Debug for TaskBox { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_tuple(self.name()).field(&format_args!("...")).finish() } @@ -50,11 +73,11 @@ pub struct TaskCanceller { impl TaskCanceller { /// Returns a wrapped `task` that will be cancelled if the `TaskCanceller` /// says so. - pub fn wrap_task(&self, task: Box) -> Box + pub fn wrap_task(&self, task: T) -> impl TaskOnce where - T: Send + Task + 'static, + T: TaskOnce, { - box CancellableTask { + CancellableTask { cancelled: self.cancelled.clone(), inner: task, } @@ -62,14 +85,14 @@ impl TaskCanceller { } /// A task that can be cancelled by toggling a shared flag. -pub struct CancellableTask { +pub struct CancellableTask { cancelled: Option>, - inner: Box, + inner: T, } impl CancellableTask where - T: Send + Task, + T: TaskOnce, { fn is_cancelled(&self) -> bool { self.cancelled.as_ref().map_or(false, |cancelled| { @@ -78,17 +101,17 @@ where } } -impl Task for CancellableTask +impl TaskOnce for CancellableTask where - T: Send + Task, + T: TaskOnce, { fn name(&self) -> &'static str { self.inner.name() } - fn run(self: Box) { + fn run_once(self) { if !self.is_cancelled() { - self.inner.run() + self.inner.run_once() } } } diff --git a/servo/components/script/task_source/dom_manipulation.rs b/servo/components/script/task_source/dom_manipulation.rs index 93cdfde95f4b..30dd3df88518 100644 --- a/servo/components/script/task_source/dom_manipulation.rs +++ b/servo/components/script/task_source/dom_manipulation.rs @@ -13,7 +13,7 @@ use servo_atoms::Atom; use std::fmt; use std::result::Result; use std::sync::mpsc::Sender; -use task::{Task, TaskCanceller}; +use task::{TaskCanceller, TaskOnce}; use task_source::TaskSource; #[derive(Clone, JSTraceable)] @@ -28,15 +28,15 @@ impl fmt::Debug for DOMManipulationTaskSource { impl TaskSource for DOMManipulationTaskSource { fn queue_with_canceller( &self, - msg: Box, + task: T, canceller: &TaskCanceller, ) -> Result<(), ()> where - T: Task + Send + 'static, + T: TaskOnce + 'static, { let msg = MainThreadScriptMsg::Common(CommonScriptMsg::Task( ScriptThreadEventCategory::ScriptEvent, - canceller.wrap_task(msg), + box canceller.wrap_task(task), )); self.0.send(msg).map_err(|_| ()) } @@ -50,7 +50,7 @@ impl DOMManipulationTaskSource { cancelable: EventCancelable, window: &Window) { let target = Trusted::new(target); - let task = box EventTask { + let task = EventTask { target: target, name: name, bubbles: bubbles, @@ -61,6 +61,6 @@ impl DOMManipulationTaskSource { pub fn queue_simple_event(&self, target: &EventTarget, name: Atom, window: &Window) { let target = Trusted::new(target); - let _ = self.queue(box SimpleEventTask { target, name }, window.upcast()); + let _ = self.queue(SimpleEventTask { target, name }, window.upcast()); } } diff --git a/servo/components/script/task_source/file_reading.rs b/servo/components/script/task_source/file_reading.rs index 1d44a4087d6f..fc9af75794c5 100644 --- a/servo/components/script/task_source/file_reading.rs +++ b/servo/components/script/task_source/file_reading.rs @@ -6,7 +6,7 @@ use dom::domexception::DOMErrorName; use dom::filereader::{FileReader, TrustedFileReader, GenerationId, ReadMetaData}; use script_runtime::{CommonScriptMsg, ScriptThreadEventCategory, ScriptChan}; use std::sync::Arc; -use task::{Task, TaskCanceller}; +use task::{TaskCanceller, TaskOnce}; use task_source::TaskSource; #[derive(JSTraceable)] @@ -21,21 +21,21 @@ impl Clone for FileReadingTaskSource { impl TaskSource for FileReadingTaskSource { fn queue_with_canceller( &self, - msg: Box, + task: T, canceller: &TaskCanceller, ) -> Result<(), ()> where - T: Send + Task + 'static, + T: TaskOnce + 'static, { self.0.send(CommonScriptMsg::Task( ScriptThreadEventCategory::FileRead, - canceller.wrap_task(msg), + box canceller.wrap_task(task), )) } } -impl Task for FileReadingTask { - fn run(self: Box) { +impl TaskOnce for FileReadingTask { + fn run_once(self) { self.handle_task(); } } diff --git a/servo/components/script/task_source/mod.rs b/servo/components/script/task_source/mod.rs index 40b3c2f32612..4818ba2c80c3 100644 --- a/servo/components/script/task_source/mod.rs +++ b/servo/components/script/task_source/mod.rs @@ -11,18 +11,21 @@ pub mod user_interaction; use dom::globalscope::GlobalScope; use std::result::Result; -use task::{Task, TaskCanceller}; +use task::{TaskCanceller, TaskOnce}; pub trait TaskSource { fn queue_with_canceller( &self, - msg: Box, + task: T, canceller: &TaskCanceller, ) -> Result<(), ()> where - T: Send + Task + 'static; + T: TaskOnce + 'static; - fn queue(&self, msg: Box, global: &GlobalScope) -> Result<(), ()> { - self.queue_with_canceller(msg, &global.task_canceller()) + fn queue(&self, task: T, global: &GlobalScope) -> Result<(), ()> + where + T: TaskOnce + 'static, + { + self.queue_with_canceller(task, &global.task_canceller()) } } diff --git a/servo/components/script/task_source/networking.rs b/servo/components/script/task_source/networking.rs index 5d339037729e..8b167c5d9053 100644 --- a/servo/components/script/task_source/networking.rs +++ b/servo/components/script/task_source/networking.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCategory}; -use task::{Task, TaskCanceller}; +use task::{TaskCanceller, TaskOnce}; use task_source::TaskSource; #[derive(JSTraceable)] @@ -18,15 +18,15 @@ impl Clone for NetworkingTaskSource { impl TaskSource for NetworkingTaskSource { fn queue_with_canceller( &self, - msg: Box, + task: T, canceller: &TaskCanceller, ) -> Result<(), ()> where - T: Send + Task + 'static, + T: TaskOnce + 'static, { self.0.send(CommonScriptMsg::Task( ScriptThreadEventCategory::NetworkEvent, - canceller.wrap_task(msg), + box canceller.wrap_task(task), )) } } @@ -34,10 +34,13 @@ impl TaskSource for NetworkingTaskSource { impl NetworkingTaskSource { /// This queues a task that will not be cancelled when its associated /// global scope gets destroyed. - pub fn queue_unconditionally(&self, msg: Box) -> Result<(), ()> + pub fn queue_unconditionally(&self, task: T) -> Result<(), ()> where - T: Task + Send + 'static, + T: TaskOnce + 'static, { - self.0.send(CommonScriptMsg::Task(ScriptThreadEventCategory::NetworkEvent, msg)) + self.0.send(CommonScriptMsg::Task( + ScriptThreadEventCategory::NetworkEvent, + box task, + )) } } diff --git a/servo/components/script/task_source/performance_timeline.rs b/servo/components/script/task_source/performance_timeline.rs index 0b379d496f49..1a3ffeb7fc72 100644 --- a/servo/components/script/task_source/performance_timeline.rs +++ b/servo/components/script/task_source/performance_timeline.rs @@ -11,7 +11,7 @@ use dom::globalscope::GlobalScope; use script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCategory}; use std::fmt; use std::result::Result; -use task::{Task, TaskCanceller}; +use task::{TaskCanceller, TaskOnce}; use task_source::TaskSource; #[derive(JSTraceable)] @@ -32,15 +32,15 @@ impl fmt::Debug for PerformanceTimelineTaskSource { impl TaskSource for PerformanceTimelineTaskSource { fn queue_with_canceller( &self, - msg: Box, + task: T, canceller: &TaskCanceller, ) -> Result<(), ()> where - T: Send + Task + 'static, + T: TaskOnce + 'static, { let msg = CommonScriptMsg::Task( ScriptThreadEventCategory::PerformanceTimelineTask, - canceller.wrap_task(msg) + box canceller.wrap_task(task) ); self.0.send(msg).map_err(|_| ()) } @@ -51,7 +51,7 @@ impl PerformanceTimelineTaskSource { let owner = Trusted::new(&*global.performance()); // FIXME(nox): Why are errors silenced here? let _ = self.queue( - box task!(notify_performance_observers: move || { + task!(notify_performance_observers: move || { owner.root().notify_observers(); }), global, diff --git a/servo/components/script/task_source/user_interaction.rs b/servo/components/script/task_source/user_interaction.rs index 8b36a61e9d09..9891f4745296 100644 --- a/servo/components/script/task_source/user_interaction.rs +++ b/servo/components/script/task_source/user_interaction.rs @@ -13,7 +13,7 @@ use servo_atoms::Atom; use std::fmt; use std::result::Result; use std::sync::mpsc::Sender; -use task::{Task, TaskCanceller}; +use task::{TaskCanceller, TaskOnce}; use task_source::TaskSource; #[derive(Clone, JSTraceable)] @@ -28,15 +28,15 @@ impl fmt::Debug for UserInteractionTaskSource { impl TaskSource for UserInteractionTaskSource { fn queue_with_canceller( &self, - msg: Box, + task: T, canceller: &TaskCanceller, ) -> Result<(), ()> where - T: Task + Send + 'static, + T: TaskOnce + 'static, { let msg = MainThreadScriptMsg::Common(CommonScriptMsg::Task( ScriptThreadEventCategory::InputEvent, - canceller.wrap_task(msg), + box canceller.wrap_task(task), )); self.0.send(msg).map_err(|_| ()) } @@ -50,7 +50,7 @@ impl UserInteractionTaskSource { cancelable: EventCancelable, window: &Window) { let target = Trusted::new(target); - let task = box EventTask { target, name, bubbles, cancelable }; + let task = EventTask { target, name, bubbles, cancelable }; let _ = self.queue(task, window.upcast()); } }