diff --git a/components/script/dom/bindings/refcounted.rs b/components/script/dom/bindings/refcounted.rs index 1be8a369d8f..4da753cb833 100644 --- a/components/script/dom/bindings/refcounted.rs +++ b/components/script/dom/bindings/refcounted.rs @@ -32,7 +32,6 @@ use dom::promise::Promise; use js::jsapi::JSAutoCompartment; use js::jsapi::JSTracer; use libc; -use script_thread::Task; use std::cell::RefCell; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::hash_map::HashMap; @@ -41,6 +40,7 @@ use std::marker::PhantomData; use std::os; use std::rc::Rc; use std::sync::{Arc, Weak}; +use task::Task; #[allow(missing_docs)] // FIXME diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs index 35e6fdde3b1..2cd557d52b8 100644 --- a/components/script/dom/bluetooth.rs +++ b/components/script/dom/bluetooth.rs @@ -35,12 +35,12 @@ use ipc_channel::router::ROUTER; use js::conversions::ConversionResult; use js::jsapi::{JSAutoCompartment, JSContext, JSObject}; use js::jsval::{ObjectValue, UndefinedValue}; -use script_thread::Task; use std::cell::Ref; use std::collections::HashMap; use std::rc::Rc; use std::str::FromStr; use std::sync::{Arc, Mutex}; +use task::Task; 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."; diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index e0c5380cc59..90853a28e7f 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -113,7 +113,7 @@ use net_traits::response::HttpsState; use num_traits::ToPrimitive; use script_layout_interface::message::{Msg, ReflowQueryType}; use script_runtime::{CommonScriptMsg, ScriptThreadEventCategory}; -use script_thread::{MainThreadScriptMsg, ScriptThread, Task}; +use script_thread::{MainThreadScriptMsg, ScriptThread}; use script_traits::{AnimationState, CompositorEvent, DocumentActivity}; use script_traits::{MouseButton, MouseEventType, MozBrowserEvent}; use script_traits::{MsDuration, ScriptMsg, TouchpadPressurePhase}; @@ -142,6 +142,7 @@ use style::shared_lock::{SharedRwLock as StyleSharedRwLock, SharedRwLockReadGuar use style::str::{HTML_SPACE_CHARACTERS, split_html_space_chars, str_join}; use style::stylesheet_set::StylesheetSet; use style::stylesheets::{Stylesheet, StylesheetContents, Origin, OriginSet}; +use task::Task; use task_source::TaskSource; use time; use timers::OneshotTimerCallback; diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index f6322c65960..56fbcc0fcaf 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -87,7 +87,7 @@ use js::jsval::JSVal; use net_traits::request::CorsSettings; use ref_filter_map::ref_filter_map; use script_layout_interface::message::ReflowQueryType; -use script_thread::{ScriptThread, Task}; +use script_thread::ScriptThread; use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity}; use selectors::matching::{ElementSelectorFlags, LocalMatchingContext, MatchingContext, MatchingMode}; use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS}; @@ -119,6 +119,7 @@ use style::thread_state; use style::values::{CSSFloat, Either}; use style::values::{specified, computed}; use stylesheet_loader::StylesheetOwner; +use task::Task; // 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. diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs index fb6bf9c3b61..f5143ec72c4 100644 --- a/components/script/dom/event.rs +++ b/components/script/dom/event.rs @@ -20,10 +20,10 @@ use dom::node::Node; use dom::virtualmethods::vtable_for; use dom::window::Window; use dom_struct::dom_struct; -use script_thread::Task; use servo_atoms::Atom; use std::cell::Cell; use std::default::Default; +use task::Task; use time; #[dom_struct] diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs index 2bd5f32261e..438200e3bab 100644 --- a/components/script/dom/eventsource.rs +++ b/components/script/dom/eventsource.rs @@ -27,13 +27,13 @@ use net_traits::{CoreResourceMsg, FetchMetadata, FetchResponseMsg, FetchResponse use net_traits::request::{CacheMode, CorsSettings, CredentialsMode}; use net_traits::request::{RequestInit, RequestMode}; use network_listener::{NetworkListener, PreInvoke}; -use script_thread::Task; use servo_atoms::Atom; use servo_url::ServoUrl; use std::cell::Cell; use std::mem; use std::str::{Chars, FromStr}; use std::sync::{Arc, Mutex}; +use task::Task; use task_source::TaskSource; use timers::OneshotTimerCallback; use utf8; diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs index d954e1431ef..b2f5b1ca36f 100644 --- a/components/script/dom/filereader.rs +++ b/components/script/dom/filereader.rs @@ -29,12 +29,12 @@ use js::jsapi::JSAutoCompartment; use js::jsapi::JSContext; use js::jsval::{self, JSVal}; use js::typedarray::{ArrayBuffer, CreateWith}; -use script_thread::TaskCanceller; use servo_atoms::Atom; use std::cell::Cell; use std::ptr; use std::sync::Arc; use std::thread; +use task::TaskCanceller; use task_source::TaskSource; use task_source::file_reading::{FileReadingTask, FileReadingTaskSource}; diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index e661e315ea4..529b1791d59 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -38,7 +38,7 @@ use msg::constellation_msg::PipelineId; use net_traits::{CoreResourceThread, ResourceThreads, IpcSend}; use profile_traits::{mem, time}; use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort}; -use script_thread::{MainThreadScriptChan, ScriptThread, TaskCanceller}; +use script_thread::{MainThreadScriptChan, ScriptThread}; use script_traits::{MsDuration, ScriptToConstellationChan, TimerEvent}; use script_traits::{TimerEventId, TimerSchedulerMsg, TimerSource}; use servo_url::{MutableOrigin, ServoUrl}; @@ -47,6 +47,7 @@ use std::collections::HashMap; use std::collections::hash_map::Entry; use std::ffi::CString; use std::rc::Rc; +use task::TaskCanceller; use task_source::file_reading::FileReadingTaskSource; use task_source::networking::NetworkingTaskSource; use task_source::performance_timeline::PerformanceTimelineTaskSource; diff --git a/components/script/dom/htmldetailselement.rs b/components/script/dom/htmldetailselement.rs index 4f4087b4c38..8cd5133dca7 100644 --- a/components/script/dom/htmldetailselement.rs +++ b/components/script/dom/htmldetailselement.rs @@ -16,8 +16,8 @@ use dom::node::{Node, window_from_node}; use dom::virtualmethods::VirtualMethods; use dom_struct::dom_struct; use html5ever::{LocalName, Prefix}; -use script_thread::Task; use std::cell::Cell; +use task::Task; use task_source::TaskSource; #[dom_struct] diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index 43771b17890..ca14df723b8 100755 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -49,7 +49,7 @@ use html5ever::{LocalName, Prefix}; use hyper::header::{Charset, ContentDisposition, ContentType, DispositionParam, DispositionType}; use hyper::method::Method; use msg::constellation_msg::PipelineId; -use script_thread::{MainThreadScriptMsg, Task}; +use script_thread::MainThreadScriptMsg; use script_traits::LoadData; use servo_rand::random; use std::borrow::ToOwned; @@ -57,6 +57,7 @@ use std::cell::Cell; use std::sync::mpsc::Sender; use style::attr::AttrValue; use style::str::split_html_space_chars; +use task::Task; use task_source::TaskSource; #[derive(Clone, Copy, HeapSizeOf, JSTraceable, PartialEq)] diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index fa6639ad422..0452c40d2f9 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -43,7 +43,7 @@ use js::jsval::{NullValue, UndefinedValue}; use msg::constellation_msg::{FrameType, BrowsingContextId, PipelineId, TopLevelBrowsingContextId, TraversalDirection}; use net_traits::response::HttpsState; use script_layout_interface::message::ReflowQueryType; -use script_thread::{ScriptThread, Task}; +use script_thread::ScriptThread; use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, JsEvalResult, LoadData, UpdatePipelineIdReason}; use script_traits::{MozBrowserEvent, NewLayoutInfo, ScriptMsg}; use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed}; @@ -54,6 +54,7 @@ use servo_url::ServoUrl; use std::cell::Cell; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; use style::context::ReflowGoal; +use task::Task; use task_source::TaskSource; bitflags! { diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 23348c9d263..9967728e745 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -48,7 +48,7 @@ use net_traits::image_cache::UsePlaceholder; use net_traits::request::{RequestInit, Type as RequestType}; use network_listener::{NetworkListener, PreInvoke}; use num_traits::ToPrimitive; -use script_thread::{ScriptThread, Task}; +use script_thread::ScriptThread; use servo_url::ServoUrl; use servo_url::origin::ImmutableOrigin; use std::cell::{Cell, RefMut}; @@ -56,6 +56,7 @@ use std::default::Default; use std::i32; use std::sync::{Arc, Mutex}; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; +use task::Task; use task_source::TaskSource; #[derive(Clone, Copy, HeapSizeOf, JSTraceable)] diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 0f4549b0809..f307dc2e733 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -35,10 +35,11 @@ use microtask::{Microtask, MicrotaskRunnable}; use net_traits::{FetchResponseListener, FetchMetadata, Metadata, NetworkError}; use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as RequestType}; use network_listener::{NetworkListener, PreInvoke}; -use script_thread::{ScriptThread, Task}; +use script_thread::ScriptThread; use servo_url::ServoUrl; use std::cell::Cell; use std::sync::{Arc, Mutex}; +use task::Task; use task_source::TaskSource; use time::{self, Timespec, Duration}; diff --git a/components/script/dom/serviceworker.rs b/components/script/dom/serviceworker.rs index add6279e0a0..74169428453 100644 --- a/components/script/dom/serviceworker.rs +++ b/components/script/dom/serviceworker.rs @@ -16,10 +16,10 @@ use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; use dom_struct::dom_struct; use js::jsapi::{HandleValue, JSContext}; -use script_thread::Task; use script_traits::{ScriptMsg, DOMMessage}; use servo_url::ServoUrl; use std::cell::Cell; +use task::Task; pub type TrustedServiceWorkerAddress = Trusted; diff --git a/components/script/dom/storage.rs b/components/script/dom/storage.rs index 65c21bc6706..fdd2ae4c504 100644 --- a/components/script/dom/storage.rs +++ b/components/script/dom/storage.rs @@ -17,9 +17,9 @@ use dom_struct::dom_struct; use ipc_channel::ipc::{self, IpcSender}; use net_traits::IpcSend; use net_traits::storage_thread::{StorageThreadMsg, StorageType}; -use script_thread::Task; use script_traits::ScriptMsg; use servo_url::ServoUrl; +use task::Task; use task_source::TaskSource; #[dom_struct] diff --git a/components/script/dom/vrdisplay.rs b/components/script/dom/vrdisplay.rs index 9bc40bd5a82..2b2ab80f2e5 100644 --- a/components/script/dom/vrdisplay.rs +++ b/components/script/dom/vrdisplay.rs @@ -36,12 +36,12 @@ use ipc_channel::ipc::{self, IpcSender}; use js::jsapi::JSContext; use script_runtime::CommonScriptMsg; use script_runtime::ScriptThreadEventCategory::WebVREvent; -use script_thread::Task; use std::cell::Cell; use std::mem; use std::rc::Rc; use std::sync::mpsc; use std::thread; +use task::Task; use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVRFrameData, WebVRLayer, WebVRMsg}; #[dom_struct] diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index a390381b924..52b2dcc85d6 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -31,13 +31,13 @@ use net_traits::CoreResourceMsg::WebsocketConnect; use net_traits::MessageData; use script_runtime::CommonScriptMsg; use script_runtime::ScriptThreadEventCategory::WebSocketEvent; -use script_thread::{Task, TaskCanceller}; use servo_url::ServoUrl; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::cell::Cell; use std::ptr; use std::thread; +use task::{Task, TaskCanceller}; use task_source::TaskSource; use task_source::networking::NetworkingTaskSource; diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 3b555ca7c4c..7492962e682 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -76,8 +76,8 @@ use script_layout_interface::rpc::{ContentBoxResponse, ContentBoxesResponse, Lay use script_layout_interface::rpc::{MarginStyleResponse, NodeScrollRootIdResponse}; use script_layout_interface::rpc::{ResolvedStyleResponse, TextIndexResponse}; use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, ScriptThreadEventCategory}; -use script_thread::{ImageCacheMsg, MainThreadScriptChan, MainThreadScriptMsg, Task}; -use script_thread::{ScriptThread, SendableMainThreadScriptChan, TaskCanceller}; +use script_thread::{ImageCacheMsg, MainThreadScriptChan, MainThreadScriptMsg}; +use script_thread::{ScriptThread, SendableMainThreadScriptChan}; use script_traits::{ConstellationControlMsg, DocumentState, LoadData, MozBrowserEvent}; use script_traits::{ScriptToConstellationChan, ScriptMsg, ScrollState, TimerEvent, TimerEventId}; use script_traits::{TimerSchedulerMsg, UntrustedNodeAddress, WindowSizeData, WindowSizeType}; @@ -111,6 +111,7 @@ use style::selector_parser::PseudoElement; use style::str::HTML_SPACE_CHARACTERS; use style::stylesheets::CssRuleType; use style_traits::PARSING_MODE_DEFAULT; +use task::{Task, TaskCanceller}; use task_source::dom_manipulation::DOMManipulationTaskSource; use task_source::file_reading::FileReadingTaskSource; use task_source::history_traversal::HistoryTraversalTaskSource; diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index 498cae4b0f4..70efc86606a 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -25,12 +25,12 @@ use dom_struct::dom_struct; use ipc_channel::ipc; use js::jsapi::{HandleValue, JSAutoCompartment, JSContext, NullHandleValue}; use js::jsval::UndefinedValue; -use script_thread::Task; use script_traits::WorkerScriptLoadOrigin; use std::cell::Cell; use std::sync::{Arc, Mutex}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::{Sender, channel}; +use task::Task; pub type TrustedWorkerAddress = Trusted; diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index c26fcc63fdb..57017f5cd55 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -33,7 +33,6 @@ use js::rust::Runtime; use net_traits::{IpcSend, load_whole_resource}; use net_traits::request::{CredentialsMode, Destination, RequestInit as NetRequestInit, Type as RequestType}; use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, get_reports}; -use script_thread::TaskCanceller; use script_traits::{TimerEvent, TimerEventId}; use script_traits::WorkerGlobalScopeInit; use servo_url::{MutableOrigin, ServoUrl}; @@ -42,6 +41,7 @@ use std::rc::Rc; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::Receiver; +use task::TaskCanceller; use task_source::file_reading::FileReadingTaskSource; use task_source::networking::NetworkingTaskSource; use task_source::performance_timeline::PerformanceTimelineTaskSource; diff --git a/components/script/dom/worklet.rs b/components/script/dom/worklet.rs index 9bfec3c78cb..b55f9d328a0 100644 --- a/components/script/dom/worklet.rs +++ b/components/script/dom/worklet.rs @@ -51,7 +51,7 @@ use script_runtime::CommonScriptMsg; use script_runtime::ScriptThreadEventCategory; use script_runtime::StackRootTLS; use script_runtime::new_rt_and_cx; -use script_thread::{MainThreadScriptMsg, ScriptThread, Task}; +use script_thread::{MainThreadScriptMsg, ScriptThread}; use servo_rand; use servo_url::ImmutableOrigin; use servo_url::ServoUrl; @@ -69,6 +69,7 @@ use std::thread; use style::thread_state; use swapper::Swapper; use swapper::swapper; +use task::Task; use uuid::Uuid; // Magic numbers diff --git a/components/script/lib.rs b/components/script/lib.rs index 5ba671440bd..b015a5407b0 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -123,6 +123,7 @@ pub mod script_thread; mod serviceworker_manager; mod serviceworkerjob; mod stylesheet_loader; +mod task; mod task_source; pub mod test; pub mod textinput; diff --git a/components/script/network_listener.rs b/components/script/network_listener.rs index aa167ecdfca..8b291128065 100644 --- a/components/script/network_listener.rs +++ b/components/script/network_listener.rs @@ -3,8 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use net_traits::{Action, FetchResponseListener, FetchResponseMsg}; -use script_thread::{Task, TaskCanceller}; use std::sync::{Arc, Mutex}; +use task::{Task, TaskCanceller}; use task_source::TaskSource; use task_source::networking::NetworkingTaskSource; diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs index b12649668e5..270dd0cdafe 100644 --- a/components/script/script_runtime.rs +++ b/components/script/script_runtime.rs @@ -23,7 +23,7 @@ use js::panic::wrap_panic; use js::rust::Runtime; use microtask::{EnqueuedPromiseCallback, Microtask}; use profile_traits::mem::{Report, ReportKind, ReportsChan}; -use script_thread::{STACK_ROOTS, Task, trace_thread}; +use script_thread::{STACK_ROOTS, trace_thread}; use servo_config::opts; use servo_config::prefs::PREFS; use std::cell::Cell; @@ -35,6 +35,7 @@ use std::os::raw::c_void; use std::panic::AssertUnwindSafe; use std::ptr; use style::thread_state; +use task::Task; use time::{Tm, now}; /// Common messages used to control the event loops in both the script and the worker diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 21989316864..56f47cfdbef 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -105,15 +105,12 @@ use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; use std::cell::Cell; use std::collections::{hash_map, HashMap, HashSet}; use std::default::Default; -use std::fmt; -use std::intrinsics; use std::ops::Deref; use std::option::Option; use std::ptr; use std::rc::Rc; use std::result::Result; use std::sync::Arc; -use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::{Receiver, Select, Sender, channel}; use std::thread; use style::context::ReflowGoal; @@ -206,62 +203,6 @@ impl InProgressLoad { } } -/// Encapsulated state required to create cancellable tasks from non-script threads. -pub struct TaskCanceller { - pub cancelled: Option>, -} - -impl TaskCanceller { - pub fn wrap_task(&self, task: Box) -> Box - where - T: Send + Task + 'static, - { - box CancellableTask { - cancelled: self.cancelled.clone(), - inner: task, - } - } -} - -/// A task that can be discarded by toggling a shared flag. -pub struct CancellableTask { - cancelled: Option>, - inner: Box, -} - -impl CancellableTask -where - T: Send + Task, -{ - fn is_cancelled(&self) -> bool { - self.cancelled.as_ref().map_or(false, |cancelled| { - cancelled.load(Ordering::SeqCst) - }) - } -} - -impl Task for CancellableTask -where - T: Send + Task, -{ - fn run(self: Box) { - if !self.is_cancelled() { - self.inner.run() - } - } -} - -pub trait Task { - fn name(&self) -> &'static str { unsafe { intrinsics::type_name::() } } - fn run(self: Box); -} - -impl fmt::Debug for Task + Send { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_tuple(self.name()).field(&format_args!("...")).finish() - } -} - #[derive(Debug)] enum MixedMessage { FromConstellation(ConstellationControlMsg), diff --git a/components/script/serviceworkerjob.rs b/components/script/serviceworkerjob.rs index db457dc394a..fef1d02e4da 100644 --- a/components/script/serviceworkerjob.rs +++ b/components/script/serviceworkerjob.rs @@ -18,11 +18,12 @@ use dom::promise::Promise; use dom::serviceworkerregistration::ServiceWorkerRegistration; use dom::urlhelper::UrlHelper; use js::jsapi::JSAutoCompartment; -use script_thread::{ScriptThread, Task}; +use script_thread::ScriptThread; use servo_url::ServoUrl; use std::cmp::PartialEq; use std::collections::HashMap; use std::rc::Rc; +use task::Task; use task_source::TaskSource; use task_source::dom_manipulation::DOMManipulationTaskSource; diff --git a/components/script/task.rs b/components/script/task.rs new file mode 100644 index 00000000000..55c8f37aca4 --- /dev/null +++ b/components/script/task.rs @@ -0,0 +1,70 @@ +/* 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/. */ + +//! Machinery for [tasks](https://html.spec.whatwg.org/multipage/#concept-task). + +use std::fmt; +use std::intrinsics; +use std::sync::Arc; +use std::sync::atomic::{AtomicBool, Ordering}; + +/// A task that can be run. The name method is for profiling purposes. +pub trait Task { + #[allow(unsafe_code)] + fn name(&self) -> &'static str { unsafe { intrinsics::type_name::() } } + fn run(self: Box); +} + +impl fmt::Debug for Task + Send { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_tuple(self.name()).field(&format_args!("...")).finish() + } +} + +/// Encapsulated state required to create cancellable tasks from non-script threads. +pub struct TaskCanceller { + pub cancelled: Option>, +} + +impl TaskCanceller { + /// Returns a wrapped `task` that will be cancelled if the `TaskCanceller` + /// says so. + pub fn wrap_task(&self, task: Box) -> Box + where + T: Send + Task + 'static, + { + box CancellableTask { + cancelled: self.cancelled.clone(), + inner: task, + } + } +} + +/// A task that can be cancelled by toggling a shared flag. +pub struct CancellableTask { + cancelled: Option>, + inner: Box, +} + +impl CancellableTask +where + T: Send + Task, +{ + fn is_cancelled(&self) -> bool { + self.cancelled.as_ref().map_or(false, |cancelled| { + cancelled.load(Ordering::SeqCst) + }) + } +} + +impl Task for CancellableTask +where + T: Send + Task, +{ + fn run(self: Box) { + if !self.is_cancelled() { + self.inner.run() + } + } +} diff --git a/components/script/task_source/dom_manipulation.rs b/components/script/task_source/dom_manipulation.rs index f7b7a6577f8..93cdfde95f4 100644 --- a/components/script/task_source/dom_manipulation.rs +++ b/components/script/task_source/dom_manipulation.rs @@ -8,11 +8,12 @@ use dom::event::{EventBubbles, EventCancelable, EventTask, SimpleEventTask}; use dom::eventtarget::EventTarget; use dom::window::Window; use script_runtime::{CommonScriptMsg, ScriptThreadEventCategory}; -use script_thread::{MainThreadScriptMsg, Task, TaskCanceller}; +use script_thread::MainThreadScriptMsg; use servo_atoms::Atom; use std::fmt; use std::result::Result; use std::sync::mpsc::Sender; +use task::{Task, TaskCanceller}; use task_source::TaskSource; #[derive(Clone, JSTraceable)] diff --git a/components/script/task_source/file_reading.rs b/components/script/task_source/file_reading.rs index dc9a6a751dd..1d44a4087d6 100644 --- a/components/script/task_source/file_reading.rs +++ b/components/script/task_source/file_reading.rs @@ -5,8 +5,8 @@ use dom::domexception::DOMErrorName; use dom::filereader::{FileReader, TrustedFileReader, GenerationId, ReadMetaData}; use script_runtime::{CommonScriptMsg, ScriptThreadEventCategory, ScriptChan}; -use script_thread::{Task, TaskCanceller}; use std::sync::Arc; +use task::{Task, TaskCanceller}; use task_source::TaskSource; #[derive(JSTraceable)] diff --git a/components/script/task_source/mod.rs b/components/script/task_source/mod.rs index 3dbb753883e..40b3c2f3261 100644 --- a/components/script/task_source/mod.rs +++ b/components/script/task_source/mod.rs @@ -10,8 +10,8 @@ pub mod performance_timeline; pub mod user_interaction; use dom::globalscope::GlobalScope; -use script_thread::{Task, TaskCanceller}; use std::result::Result; +use task::{Task, TaskCanceller}; pub trait TaskSource { fn queue_with_canceller( diff --git a/components/script/task_source/networking.rs b/components/script/task_source/networking.rs index 56c583d775f..5d339037729 100644 --- a/components/script/task_source/networking.rs +++ b/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 script_thread::{Task, TaskCanceller}; +use task::{Task, TaskCanceller}; use task_source::TaskSource; #[derive(JSTraceable)] diff --git a/components/script/task_source/performance_timeline.rs b/components/script/task_source/performance_timeline.rs index db80789a206..938566b7a8f 100644 --- a/components/script/task_source/performance_timeline.rs +++ b/components/script/task_source/performance_timeline.rs @@ -10,9 +10,9 @@ use dom::bindings::refcounted::Trusted; use dom::globalscope::GlobalScope; use dom::performance::Performance; use script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCategory}; -use script_thread::{Task, TaskCanceller}; use std::fmt; use std::result::Result; +use task::{Task, TaskCanceller}; use task_source::TaskSource; pub struct NotifyPerformanceObserverTask { diff --git a/components/script/task_source/user_interaction.rs b/components/script/task_source/user_interaction.rs index 3e84e0fb19a..8b36a61e9d0 100644 --- a/components/script/task_source/user_interaction.rs +++ b/components/script/task_source/user_interaction.rs @@ -8,11 +8,12 @@ use dom::event::{EventBubbles, EventCancelable, EventTask}; use dom::eventtarget::EventTarget; use dom::window::Window; use script_runtime::{CommonScriptMsg, ScriptThreadEventCategory}; -use script_thread::{MainThreadScriptMsg, Task, TaskCanceller}; +use script_thread::MainThreadScriptMsg; use servo_atoms::Atom; use std::fmt; use std::result::Result; use std::sync::mpsc::Sender; +use task::{Task, TaskCanceller}; use task_source::TaskSource; #[derive(Clone, JSTraceable)]