aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2014-12-02 16:54:43 -0800
committerJosh Matthews <josh@joshmatthews.net>2014-12-29 13:53:49 -0500
commit9a7cd3113403fe44a8919f049720b67bfa92c9f1 (patch)
treebec170bff412ced10ce251846c828e5216ccf81e /components/script/dom/bindings
parent2f059c15e76bd02a4cd6baa4a946f64ab8e6878a (diff)
downloadservo-9a7cd3113403fe44a8919f049720b67bfa92c9f1.tar.gz
servo-9a7cd3113403fe44a8919f049720b67bfa92c9f1.zip
Force all messages to worker tasks to send a TrustedWorkerAddress along with the ScriptMsg. This ensures that the main-thread Worker object is rooted for as long as there are events in flight or being processed.
Diffstat (limited to 'components/script/dom/bindings')
-rw-r--r--components/script/dom/bindings/global.rs4
-rw-r--r--components/script/dom/bindings/refcounted.rs22
-rw-r--r--components/script/dom/bindings/trace.rs8
3 files changed, 23 insertions, 11 deletions
diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs
index 4efeb7aaf67..38e018fe24f 100644
--- a/components/script/dom/bindings/global.rs
+++ b/components/script/dom/bindings/global.rs
@@ -10,7 +10,7 @@
use dom::bindings::conversions::FromJSValConvertible;
use dom::bindings::js::{JS, JSRef, Root};
use dom::bindings::utils::{Reflectable, Reflector};
-use dom::workerglobalscope::WorkerGlobalScope;
+use dom::workerglobalscope::{WorkerGlobalScope, WorkerGlobalScopeHelpers};
use dom::window;
use script_task::ScriptChan;
@@ -81,7 +81,7 @@ impl<'a> GlobalRef<'a> {
/// `ScriptChan` used to send messages to the event loop of this global's
/// thread.
- pub fn script_chan<'b>(&'b self) -> &'b ScriptChan {
+ pub fn script_chan(&self) -> Box<ScriptChan+Send> {
match *self {
GlobalRef::Window(ref window) => window.script_chan(),
GlobalRef::Worker(ref worker) => worker.script_chan(),
diff --git a/components/script/dom/bindings/refcounted.rs b/components/script/dom/bindings/refcounted.rs
index 6118408ed4c..7bffda2153d 100644
--- a/components/script/dom/bindings/refcounted.rs
+++ b/components/script/dom/bindings/refcounted.rs
@@ -42,32 +42,37 @@ local_data_key!(pub LiveReferences: LiveDOMReferences)
/// DOM object is guaranteed to live at least as long as the last outstanding
/// `Trusted<T>` instance.
pub struct Trusted<T> {
- cx: *mut JSContext,
/// A pointer to the Rust DOM object of type T, but void to allow
/// sending `Trusted<T>` between tasks, regardless of T's sendability.
ptr: *const libc::c_void,
refcount: Arc<Mutex<uint>>,
- script_chan: ScriptChan,
+ script_chan: Box<ScriptChan + Send>,
+ owner_thread: *const libc::c_void,
}
impl<T: Reflectable> Trusted<T> {
/// Create a new `Trusted<T>` instance from an existing DOM pointer. The DOM object will
/// be prevented from being GCed for the duration of the resulting `Trusted<T>` object's
/// lifetime.
- pub fn new(cx: *mut JSContext, ptr: JSRef<T>, script_chan: ScriptChan) -> Trusted<T> {
+ pub fn new(cx: *mut JSContext, ptr: JSRef<T>, script_chan: Box<ScriptChan + Send>) -> Trusted<T> {
let live_references = LiveReferences.get().unwrap();
let refcount = live_references.addref(cx, &*ptr as *const T);
Trusted {
- cx: cx,
ptr: &*ptr as *const T as *const libc::c_void,
refcount: refcount,
script_chan: script_chan,
+ owner_thread: (&*live_references) as *const _ as *const libc::c_void,
}
}
- /// Obtain a usable DOM pointer from a pinned `Trusted<T>` value. Attempts to use the
- /// resulting `Temporary<T>` off of the script thread will fail.
+ /// Obtain a usable DOM pointer from a pinned `Trusted<T>` value. Fails if used on
+ /// a different thread than the original value from which this `Trusted<T>` was
+ /// obtained.
pub fn to_temporary(&self) -> Temporary<T> {
+ assert!({
+ let live_references = LiveReferences.get().unwrap();
+ self.owner_thread == (&*live_references) as *const _ as *const libc::c_void
+ });
unsafe {
Temporary::new(JS::from_raw(self.ptr as *const T))
}
@@ -82,10 +87,10 @@ impl<T: Reflectable> Clone for Trusted<T> {
}
Trusted {
- cx: self.cx,
ptr: self.ptr,
refcount: self.refcount.clone(),
script_chan: self.script_chan.clone(),
+ owner_thread: self.owner_thread,
}
}
}
@@ -97,8 +102,7 @@ impl<T: Reflectable> Drop for Trusted<T> {
assert!(*refcount > 0);
*refcount -= 1;
if *refcount == 0 {
- let ScriptChan(ref chan) = self.script_chan;
- chan.send(ScriptMsg::RefcountCleanup(self.ptr));
+ self.script_chan.send(ScriptMsg::RefcountCleanup(self.ptr));
}
}
}
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 0538e847049..955638a7f7d 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -31,6 +31,7 @@ use dom::bindings::js::JS;
use dom::bindings::refcounted::Trusted;
use dom::bindings::utils::{Reflectable, Reflector, WindowProxyHandler};
use dom::node::{Node, TrustedNodeAddress};
+use script_task::ScriptChan;
use collections::hash::{Hash, Hasher};
use cssparser::RGBA;
@@ -219,6 +220,13 @@ no_jsmanaged_fields!(UntrustedNodeAddress)
no_jsmanaged_fields!(LengthOrPercentageOrAuto)
no_jsmanaged_fields!(RGBA)
+impl JSTraceable for Box<ScriptChan+Send> {
+ #[inline]
+ fn trace(&self, _trc: *mut JSTracer) {
+ // Do nothing
+ }
+}
+
impl<'a> JSTraceable for &'a str {
#[inline]
fn trace(&self, _: *mut JSTracer) {