From 2f059c15e76bd02a4cd6baa4a946f64ab8e6878a Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 20 Nov 2014 17:17:02 -0500 Subject: Allow refcounting arbitrary DOM objects in concert with the GC to enable safe, asynchronous/cross-task references to pinned objects. --- components/script/script_task.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'components/script/script_task.rs') diff --git a/components/script/script_task.rs b/components/script/script_task.rs index ce4d8e91735..0a202752336 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -15,6 +15,7 @@ use dom::bindings::conversions::FromJSValConvertible; use dom::bindings::conversions::StringificationBehavior; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, JSRef, RootCollection, Temporary, OptionalRootable}; +use dom::bindings::refcounted::LiveDOMReferences; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::{wrap_for_same_compartment, pre_wrap}; use dom::document::{Document, IsHTMLDocument, DocumentHelpers, DocumentSource}; @@ -70,6 +71,7 @@ use js::rust::{Cx, RtUtils}; use js; use url::Url; +use libc; use libc::size_t; use std::any::{Any, AnyRefExt}; use std::comm::{channel, Sender, Receiver, Select}; @@ -111,13 +113,13 @@ pub enum ScriptMsg { ExitWindow(PipelineId), /// Message sent through Worker.postMessage (only dispatched to /// DedicatedWorkerGlobalScope). - DOMMessage(*mut u64, size_t), + DOMMessage(TrustedWorkerAddress, *mut u64, size_t), /// Posts a message to the Worker object (dispatched to all tasks). WorkerPostMessage(TrustedWorkerAddress, *mut u64, size_t), - /// Releases one reference to the Worker object (dispatched to all tasks). - WorkerRelease(TrustedWorkerAddress), /// Generic message that encapsulates event handling. RunnableMsg(Box), + /// A DOM object's last pinned reference was removed (dispatched to all tasks). + RefcountCleanup(*const libc::c_void), } /// Encapsulates internal communication within the script task. @@ -368,6 +370,7 @@ impl ScriptTask { } pub fn new_rt_and_cx() -> (js::rust::rt, Rc) { + LiveDOMReferences::initialize(); let js_runtime = js::rust::rt(); assert!({ let ptr: *mut JSRuntime = (*js_runtime).ptr; @@ -577,10 +580,10 @@ impl ScriptTask { panic!("unexpected message"), ScriptMsg::WorkerPostMessage(addr, data, nbytes) => Worker::handle_message(addr, data, nbytes), - ScriptMsg::WorkerRelease(addr) => - Worker::handle_release(addr), ScriptMsg::RunnableMsg(runnable) => runnable.handler(), + ScriptMsg::RefcountCleanup(addr) => + LiveDOMReferences::cleanup(self.js_context.borrow().as_ref().unwrap().ptr, addr), } } -- cgit v1.2.3 From 9a7cd3113403fe44a8919f049720b67bfa92c9f1 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Tue, 2 Dec 2014 16:54:43 -0800 Subject: 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. --- components/script/script_task.rs | 42 ++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) (limited to 'components/script/script_task.rs') diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 0a202752336..ae27dc671c7 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -64,7 +64,7 @@ use geom::point::Point2D; use hyper::header::{Header, HeaderFormat}; use hyper::header::common::util as header_util; use js::jsapi::{JS_SetWrapObjectCallbacks, JS_SetGCZeal, JS_DEFAULT_ZEAL_FREQ, JS_GC}; -use js::jsapi::{JSContext, JSRuntime, JSTracer}; +use js::jsapi::{JSContext, JSRuntime}; use js::jsapi::{JS_SetGCParameter, JSGC_MAX_BYTES}; use js::jsapi::{JS_SetGCCallback, JSGCStatus, JSGC_BEGIN, JSGC_END}; use js::rust::{Cx, RtUtils}; @@ -113,7 +113,7 @@ pub enum ScriptMsg { ExitWindow(PipelineId), /// Message sent through Worker.postMessage (only dispatched to /// DedicatedWorkerGlobalScope). - DOMMessage(TrustedWorkerAddress, *mut u64, size_t), + DOMMessage(*mut u64, size_t), /// Posts a message to the Worker object (dispatched to all tasks). WorkerPostMessage(TrustedWorkerAddress, *mut u64, size_t), /// Generic message that encapsulates event handling. @@ -122,17 +122,35 @@ pub enum ScriptMsg { RefcountCleanup(*const libc::c_void), } +/// A cloneable interface for communicating with an event loop. +pub trait ScriptChan { + /// Send a message to the associated event loop. + fn send(&self, msg: ScriptMsg); + /// Clone this handle. + fn clone(&self) -> Box; +} + /// Encapsulates internal communication within the script task. -#[deriving(Clone)] -pub struct ScriptChan(pub Sender); +#[jstraceable] +pub struct NonWorkerScriptChan(pub Sender); -no_jsmanaged_fields!(ScriptChan) +impl ScriptChan for NonWorkerScriptChan { + fn send(&self, msg: ScriptMsg) { + let NonWorkerScriptChan(ref chan) = *self; + chan.send(msg); + } + + fn clone(&self) -> Box { + let NonWorkerScriptChan(ref chan) = *self; + box NonWorkerScriptChan(chan.clone()) + } +} -impl ScriptChan { +impl NonWorkerScriptChan { /// Creates a new script chan. - pub fn new() -> (Receiver, ScriptChan) { + pub fn new() -> (Receiver, Box) { let (chan, port) = channel(); - (port, ScriptChan(chan)) + (port, box NonWorkerScriptChan(chan)) } } @@ -167,7 +185,7 @@ pub struct ScriptTask { port: Receiver, /// A channel to hand out to script task-based entities that need to be able to enqueue /// events in the event queue. - chan: ScriptChan, + chan: NonWorkerScriptChan, /// A channel to hand out to tasks that need to respond to a message from the script task. control_chan: ScriptControlChan, @@ -282,7 +300,7 @@ impl ScriptTaskFactory for ScriptTask { box compositor as Box, layout_chan, script_port, - ScriptChan(script_chan), + NonWorkerScriptChan(script_chan), control_chan, control_port, constellation_chan, @@ -314,7 +332,7 @@ impl ScriptTask { compositor: Box, layout_chan: LayoutChan, port: Receiver, - chan: ScriptChan, + chan: NonWorkerScriptChan, control_chan: ScriptControlChan, control_port: Receiver, constellation_chan: ConstellationChan, @@ -583,7 +601,7 @@ impl ScriptTask { ScriptMsg::RunnableMsg(runnable) => runnable.handler(), ScriptMsg::RefcountCleanup(addr) => - LiveDOMReferences::cleanup(self.js_context.borrow().as_ref().unwrap().ptr, addr), + LiveDOMReferences::cleanup(self.get_cx(), addr), } } -- cgit v1.2.3