aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/worker.rs
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2014-11-20 17:17:02 -0500
committerJosh Matthews <josh@joshmatthews.net>2014-12-29 13:53:48 -0500
commit2f059c15e76bd02a4cd6baa4a946f64ab8e6878a (patch)
treed9a4f1401714992c00b9cf00f030a2ef884c88a2 /components/script/dom/worker.rs
parentc4b93d30e4d56e3163f7ef4fdf0701cb7e0fb33c (diff)
downloadservo-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.rs50
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(())
}