From bac9a3cf6da2932f6c24e50885a657e094c77686 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 12 Aug 2014 16:29:15 +0200 Subject: [PATCH] Distinguish the sender to the own thread and to the parent thread in DedicatedWorkerGlobalScope. The WorkerGlobalScope stores a reference to the sender for the own thread, to allow passing clones to sub-workers. The DedicatedWorkerGlobalScope additionally keeps a reference to the sender for the (unique) parent thread, to implement postMessage and memory management of the Worker object. --- src/components/script/dom/bindings/global.rs | 2 ++ .../script/dom/dedicatedworkerglobalscope.rs | 36 ++++++++++--------- src/components/script/dom/worker.rs | 5 ++- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/components/script/dom/bindings/global.rs b/src/components/script/dom/bindings/global.rs index ed7807f9d72..35b94d0e472 100644 --- a/src/components/script/dom/bindings/global.rs +++ b/src/components/script/dom/bindings/global.rs @@ -72,6 +72,8 @@ 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 { match *self { Window(ref window) => &window.script_chan, diff --git a/src/components/script/dom/dedicatedworkerglobalscope.rs b/src/components/script/dom/dedicatedworkerglobalscope.rs index bf3888cced6..08b27eb193f 100644 --- a/src/components/script/dom/dedicatedworkerglobalscope.rs +++ b/src/components/script/dom/dedicatedworkerglobalscope.rs @@ -36,6 +36,8 @@ use url::Url; pub struct DedicatedWorkerGlobalScope { workerglobalscope: WorkerGlobalScope, receiver: Untraceable>, + /// Sender to the parent thread. + parent_sender: ScriptChan, worker: Untraceable, } @@ -43,15 +45,17 @@ impl DedicatedWorkerGlobalScope { pub fn new_inherited(worker_url: Url, worker: TrustedWorkerAddress, cx: Rc, - receiver: Receiver, resource_task: ResourceTask, - script_chan: ScriptChan) + parent_sender: ScriptChan, + own_sender: ScriptChan, + receiver: Receiver) -> DedicatedWorkerGlobalScope { DedicatedWorkerGlobalScope { workerglobalscope: WorkerGlobalScope::new_inherited( DedicatedGlobalScope, worker_url, cx, resource_task, - script_chan), + own_sender), receiver: Untraceable::new(receiver), + parent_sender: parent_sender, worker: Untraceable::new(worker), } } @@ -59,13 +63,14 @@ impl DedicatedWorkerGlobalScope { pub fn new(worker_url: Url, worker: TrustedWorkerAddress, cx: Rc, - receiver: Receiver, resource_task: ResourceTask, - script_chan: ScriptChan) + parent_sender: ScriptChan, + own_sender: ScriptChan, + receiver: Receiver) -> Temporary { let scope = box DedicatedWorkerGlobalScope::new_inherited( - worker_url, worker, cx.clone(), receiver, resource_task, - script_chan); + worker_url, worker, cx.clone(), resource_task, parent_sender, + own_sender, receiver); DedicatedWorkerGlobalScopeBinding::Wrap(cx.ptr, scope) } } @@ -74,8 +79,9 @@ impl DedicatedWorkerGlobalScope { pub fn run_worker_scope(worker_url: Url, worker: TrustedWorkerAddress, resource_task: ResourceTask, - receiver: Receiver, - sender: ScriptChan) { + parent_sender: ScriptChan, + own_sender: ScriptChan, + receiver: Receiver) { TaskBuilder::new() .native() .named(format!("Web Worker at {}", worker_url.serialize())) @@ -95,8 +101,8 @@ impl DedicatedWorkerGlobalScope { let (_js_runtime, js_context) = ScriptTask::new_rt_and_cx(); let global = DedicatedWorkerGlobalScope::new( - worker_url, worker, js_context.clone(), receiver, resource_task, - sender).root(); + worker_url, worker, js_context.clone(), resource_task, + parent_sender, own_sender, receiver).root(); match js_context.evaluate_script( global.reflector().get_jsobject(), source, url.serialize(), 1) { Ok(_) => (), @@ -133,9 +139,7 @@ impl DedicatedWorkerGlobalScope { impl<'a> DedicatedWorkerGlobalScopeMethods for JSRef<'a, DedicatedWorkerGlobalScope> { fn PostMessage(&self, message: DOMString) { - let scope: &JSRef = - WorkerGlobalScopeCast::from_ref(self); - let ScriptChan(ref sender) = *scope.script_chan(); + let ScriptChan(ref sender) = self.parent_sender; sender.send(WorkerPostMessage(*self.worker, message)); } } @@ -146,9 +150,7 @@ trait PrivateDedicatedWorkerGlobalScopeHelpers { impl<'a> PrivateDedicatedWorkerGlobalScopeHelpers for JSRef<'a, DedicatedWorkerGlobalScope> { fn delayed_release_worker(&self) { - let scope: &JSRef = - WorkerGlobalScopeCast::from_ref(self); - let ScriptChan(ref sender) = *scope.script_chan(); + let ScriptChan(ref sender) = self.parent_sender; sender.send(WorkerRelease(*self.worker)); } } diff --git a/src/components/script/dom/worker.rs b/src/components/script/dom/worker.rs index 3b17375ee46..f5e25db68e2 100644 --- a/src/components/script/dom/worker.rs +++ b/src/components/script/dom/worker.rs @@ -29,6 +29,8 @@ pub struct Worker { eventtarget: EventTarget, refcount: Cell, global: GlobalField, + /// Sender to the Receiver associated with the DedicatedWorkerGlobalScope + /// this Worker created. sender: ScriptChan, } @@ -64,7 +66,8 @@ impl Worker { let worker_ref = worker.addref(); DedicatedWorkerGlobalScope::run_worker_scope( - worker_url, worker_ref, resource_task, receiver, sender); + worker_url, worker_ref, resource_task, global.script_chan().clone(), + sender, receiver); Ok(Temporary::from_rooted(&*worker)) }