diff options
author | Josh Matthews <josh@joshmatthews.net> | 2014-11-20 17:17:02 -0500 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2014-12-29 13:53:48 -0500 |
commit | 2f059c15e76bd02a4cd6baa4a946f64ab8e6878a (patch) | |
tree | d9a4f1401714992c00b9cf00f030a2ef884c88a2 /components/script/dom/worker.rs | |
parent | c4b93d30e4d56e3163f7ef4fdf0701cb7e0fb33c (diff) | |
download | servo-2f059c15e76bd02a4cd6baa4a946f64ab8e6878a.tar.gz servo-2f059c15e76bd02a4cd6baa4a946f64ab8e6878a.zip |
Allow refcounting arbitrary DOM objects in concert with the GC to enable safe, asynchronous/cross-task references to pinned objects.
Diffstat (limited to 'components/script/dom/worker.rs')
-rw-r--r-- | components/script/dom/worker.rs | 50 |
1 files changed, 9 insertions, 41 deletions
diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index 4d03d312223..e6708954a41 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -9,7 +9,8 @@ use dom::bindings::codegen::InheritTypes::EventTargetCast; use dom::bindings::error::{Fallible, ErrorResult}; use dom::bindings::error::Error::{Syntax, DataClone}; use dom::bindings::global::{GlobalRef, GlobalField}; -use dom::bindings::js::{JS, JSRef, Temporary}; +use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::refcounted::Trusted; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::{Reflectable, reflect_dom_object}; use dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope; @@ -20,17 +21,16 @@ use script_task::{ScriptChan, ScriptMsg}; use servo_util::str::DOMString; use js::glue::JS_STRUCTURED_CLONE_VERSION; -use js::jsapi::{JSContext, JS_AddObjectRoot, JS_RemoveObjectRoot, JSTracer}; +use js::jsapi::JSContext; use js::jsapi::{JS_ReadStructuredClone, JS_WriteStructuredClone, JS_ClearPendingException}; use js::jsval::{JSVal, UndefinedValue}; use url::UrlParser; -use libc::{c_void, size_t}; +use libc::size_t; use std::cell::Cell; use std::ptr; -pub struct TrustedWorkerAddress(pub *const c_void); -no_jsmanaged_fields!(TrustedWorkerAddress) +pub type TrustedWorkerAddress = Trusted<Worker>; #[dom_struct] pub struct Worker { @@ -71,7 +71,7 @@ impl Worker { let (receiver, sender) = ScriptChan::new(); let worker = Worker::new(global, sender.clone()).root(); - let worker_ref = worker.addref(); + let worker_ref = Trusted::new(global.get_cx(), *worker, global.script_chan().clone()); DedicatedWorkerGlobalScope::run_worker_scope( worker_url, worker_ref, resource_task, global.script_chan().clone(), @@ -82,7 +82,7 @@ impl Worker { pub fn handle_message(address: TrustedWorkerAddress, data: *mut u64, nbytes: size_t) { - let worker = unsafe { JS::from_trusted_worker_address(address).root() }; + let worker = address.to_temporary().root(); let global = worker.global.root(); @@ -99,38 +99,6 @@ impl Worker { } } -impl Worker { - // Creates a trusted address to the object, and roots it. Always pair this with a release() - pub fn addref(&self) -> TrustedWorkerAddress { - let refcount = self.refcount.get(); - if refcount == 0 { - let cx = self.global.root().root_ref().get_cx(); - unsafe { - JS_AddObjectRoot(cx, self.reflector().rootable()); - } - } - self.refcount.set(refcount + 1); - TrustedWorkerAddress(self as *const Worker as *const c_void) - } - - pub fn release(&self) { - let refcount = self.refcount.get(); - assert!(refcount > 0) - self.refcount.set(refcount - 1); - if refcount == 1 { - let cx = self.global.root().root_ref().get_cx(); - unsafe { - JS_RemoveObjectRoot(cx, self.reflector().rootable()); - } - } - } - - pub fn handle_release(address: TrustedWorkerAddress) { - let worker = unsafe { JS::from_trusted_worker_address(address).root() }; - worker.release(); - } -} - impl<'a> WorkerMethods for JSRef<'a, Worker> { fn PostMessage(self, cx: *mut JSContext, message: JSVal) -> ErrorResult { let mut data = ptr::null_mut(); @@ -144,9 +112,9 @@ impl<'a> WorkerMethods for JSRef<'a, Worker> { return Err(DataClone); } - self.addref(); + let addr = Trusted::new(cx, self, self.global.root().root_ref().script_chan().clone()); let ScriptChan(ref sender) = self.sender; - sender.send(ScriptMsg::DOMMessage(data, nbytes)); + sender.send(ScriptMsg::DOMMessage(addr, data, nbytes)); Ok(()) } |