aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/script_task.rs
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2015-10-21 16:42:30 -0400
committerJosh Matthews <josh@joshmatthews.net>2015-11-06 10:41:38 -0500
commit989e80036e078a19003f0e4eb069671b5222c77b (patch)
tree3fe8c22b82bd0521d87b4ef63464406da6555c7a /components/script/script_task.rs
parent9fea6d2e46dd917f16a5f1ec0f6484e8164c7a3a (diff)
downloadservo-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.rs39
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)) =>