diff options
Diffstat (limited to 'components/script/script_task.rs')
-rw-r--r-- | components/script/script_task.rs | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/components/script/script_task.rs b/components/script/script_task.rs index ac67e4a5996..dda6faaa85b 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -95,6 +95,7 @@ use std::option::Option; use std::ptr; use std::rc::Rc; use std::result::Result; +use std::sync::atomic::{Ordering, AtomicBool}; use std::sync::mpsc::{Receiver, Select, Sender, channel}; use std::sync::{Arc, Mutex}; use string_cache::Atom; @@ -158,7 +159,38 @@ impl InProgressLoad { } } +/// Encapsulated state required to create cancellable runnables from non-script threads. +pub struct RunnableWrapper { + pub cancelled: Arc<AtomicBool>, +} + +impl RunnableWrapper { + pub fn wrap_runnable<T: Runnable + Send + 'static>(&self, runnable: T) -> Box<Runnable + Send> { + box CancellableRunnable { + cancelled: self.cancelled.clone(), + inner: box runnable, + } + } +} + +/// A runnable that can be discarded by toggling a shared flag. +pub struct CancellableRunnable<T: Runnable + Send> { + cancelled: Arc<AtomicBool>, + inner: Box<T>, +} + +impl<T: Runnable + Send> Runnable for CancellableRunnable<T> { + fn is_cancelled(&self) -> bool { + self.cancelled.load(Ordering::Relaxed) + } + + fn handler(self: Box<CancellableRunnable<T>>) { + self.inner.handler() + } +} + pub trait Runnable { + fn is_cancelled(&self) -> bool { false } fn handler(self: Box<Self>); } @@ -990,10 +1022,13 @@ impl ScriptTask { runnable.handler(self), MainThreadScriptMsg::DocumentLoadsComplete(id) => self.handle_loads_complete(id), - MainThreadScriptMsg::Common(CommonScriptMsg::RunnableMsg(_, runnable)) => + MainThreadScriptMsg::Common(CommonScriptMsg::RunnableMsg(_, runnable)) => { // The category of the runnable is ignored by the pattern, however // it is still respected by profiling (see categorize_msg). - runnable.handler(), + if !runnable.is_cancelled() { + runnable.handler() + } + } MainThreadScriptMsg::Common(CommonScriptMsg::RefcountCleanup(addr)) => LiveDOMReferences::cleanup(addr), MainThreadScriptMsg::Common(CommonScriptMsg::CollectReports(reports_chan)) => |