diff options
author | Josh Matthews <josh@joshmatthews.net> | 2015-10-21 16:42:30 -0400 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2015-11-06 10:41:38 -0500 |
commit | 989e80036e078a19003f0e4eb069671b5222c77b (patch) | |
tree | 3fe8c22b82bd0521d87b4ef63464406da6555c7a /components/script/script_task.rs | |
parent | 9fea6d2e46dd917f16a5f1ec0f6484e8164c7a3a (diff) | |
download | servo-989e80036e078a19003f0e4eb069671b5222c77b.tar.gz servo-989e80036e078a19003f0e4eb069671b5222c77b.zip |
Implement cancellable runnables.
Additionally, make image load events cancellable. Resolves #7731.
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)) => |