diff options
author | Josh Matthews <josh@joshmatthews.net> | 2014-12-02 16:54:43 -0800 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2014-12-29 13:53:49 -0500 |
commit | 9a7cd3113403fe44a8919f049720b67bfa92c9f1 (patch) | |
tree | bec170bff412ced10ce251846c828e5216ccf81e /components/script/dom/bindings | |
parent | 2f059c15e76bd02a4cd6baa4a946f64ab8e6878a (diff) | |
download | servo-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.rs | 4 | ||||
-rw-r--r-- | components/script/dom/bindings/refcounted.rs | 22 | ||||
-rw-r--r-- | components/script/dom/bindings/trace.rs | 8 |
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) { |