From 4f7c7fc808867d68ec15f172711a94af2b9a43ab Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 12 Aug 2014 11:10:33 +0200 Subject: [PATCH 1/4] Pass the script channel to DedicatedWorkerGlobalScope::run_worker_scope rather than creating it there. This allows us to create the Worker object before calling DedicatedWorkerGlobalScope::run_worker_scope, which is necessary to pass a pointer to the worker to it. --- src/components/script/dom/dedicatedworkerglobalscope.rs | 7 +++---- src/components/script/dom/worker.rs | 5 +++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/script/dom/dedicatedworkerglobalscope.rs b/src/components/script/dom/dedicatedworkerglobalscope.rs index f9e3210715e..a3757bf3b0b 100644 --- a/src/components/script/dom/dedicatedworkerglobalscope.rs +++ b/src/components/script/dom/dedicatedworkerglobalscope.rs @@ -62,9 +62,9 @@ impl DedicatedWorkerGlobalScope { impl DedicatedWorkerGlobalScope { pub fn run_worker_scope(worker_url: Url, - resource_task: ResourceTask) -> ScriptChan { - let (receiver, sender) = ScriptChan::new(); - let sender_clone = sender.clone(); + resource_task: ResourceTask, + receiver: Receiver, + sender: ScriptChan) { TaskBuilder::new() .native() .named(format!("Web Worker at {}", worker_url.serialize())) @@ -109,7 +109,6 @@ impl DedicatedWorkerGlobalScope { } } }); - return sender_clone; } } diff --git a/src/components/script/dom/worker.rs b/src/components/script/dom/worker.rs index 670ae7a5beb..5007f212f9a 100644 --- a/src/components/script/dom/worker.rs +++ b/src/components/script/dom/worker.rs @@ -45,8 +45,9 @@ impl Worker { }; let resource_task = global.resource_task(); - let sender = DedicatedWorkerGlobalScope::run_worker_scope( - worker_url, resource_task); + let (receiver, sender) = ScriptChan::new(); + DedicatedWorkerGlobalScope::run_worker_scope( + worker_url, resource_task, receiver, sender.clone()); Ok(Worker::new(global, sender)) } } From e8bd66cfa9ae46be42d22b74275c8af80c055faa Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 18 Jul 2014 12:24:15 +0200 Subject: [PATCH 2/4] Store a pointer to the Worker in the DedicatedWorkerGlobalScope. --- src/components/script/dom/bindings/js.rs | 10 +++ .../script/dom/dedicatedworkerglobalscope.rs | 34 +++++++++-- src/components/script/dom/worker.rs | 61 +++++++++++++++++-- src/components/script/script_task.rs | 4 ++ 4 files changed, 99 insertions(+), 10 deletions(-) diff --git a/src/components/script/dom/bindings/js.rs b/src/components/script/dom/bindings/js.rs index 6a57b45449f..ab8b3e3c7f5 100644 --- a/src/components/script/dom/bindings/js.rs +++ b/src/components/script/dom/bindings/js.rs @@ -48,6 +48,7 @@ use dom::bindings::utils::{Reflector, Reflectable}; use dom::node::Node; use dom::xmlhttprequest::{XMLHttpRequest, TrustedXHRAddress}; +use dom::worker::{Worker, TrustedWorkerAddress}; use js::jsapi::JSObject; use layout_interface::TrustedNodeAddress; use script_task::StackRoots; @@ -143,6 +144,15 @@ impl JS { } } +impl JS { + pub unsafe fn from_trusted_worker_address(inner: TrustedWorkerAddress) -> JS { + let TrustedWorkerAddress(addr) = inner; + JS { + ptr: addr as *const Worker + } + } +} + impl JS { /// Create a new JS-owned value wrapped from a raw Rust pointer. pub unsafe fn from_raw(raw: *const T) -> JS { diff --git a/src/components/script/dom/dedicatedworkerglobalscope.rs b/src/components/script/dom/dedicatedworkerglobalscope.rs index a3757bf3b0b..654183757f6 100644 --- a/src/components/script/dom/dedicatedworkerglobalscope.rs +++ b/src/components/script/dom/dedicatedworkerglobalscope.rs @@ -12,10 +12,12 @@ use dom::bindings::utils::{Reflectable, Reflector}; use dom::eventtarget::EventTarget; use dom::eventtarget::WorkerGlobalScopeTypeId; use dom::messageevent::MessageEvent; +use dom::worker::{Worker, TrustedWorkerAddress}; use dom::workerglobalscope::DedicatedGlobalScope; use dom::workerglobalscope::WorkerGlobalScope; use dom::xmlhttprequest::XMLHttpRequest; -use script_task::{ScriptTask, ScriptChan, ScriptMsg, DOMMessage, XHRProgressMsg}; +use script_task::{ScriptTask, ScriptChan}; +use script_task::{ScriptMsg, DOMMessage, XHRProgressMsg, WorkerRelease}; use script_task::StackRootTLS; use servo_net::resource_task::{ResourceTask, load_whole_resource}; @@ -31,10 +33,12 @@ use url::Url; pub struct DedicatedWorkerGlobalScope { workerglobalscope: WorkerGlobalScope, receiver: Untraceable>, + worker: Untraceable, } impl DedicatedWorkerGlobalScope { pub fn new_inherited(worker_url: Url, + worker: TrustedWorkerAddress, cx: Rc, receiver: Receiver, resource_task: ResourceTask, @@ -45,23 +49,27 @@ impl DedicatedWorkerGlobalScope { DedicatedGlobalScope, worker_url, cx, resource_task, script_chan), receiver: Untraceable::new(receiver), + worker: Untraceable::new(worker), } } pub fn new(worker_url: Url, + worker: TrustedWorkerAddress, cx: Rc, receiver: Receiver, resource_task: ResourceTask, script_chan: ScriptChan) -> Temporary { let scope = box DedicatedWorkerGlobalScope::new_inherited( - worker_url, cx.clone(), receiver, resource_task, script_chan); + worker_url, worker, cx.clone(), receiver, resource_task, + script_chan); DedicatedWorkerGlobalScopeBinding::Wrap(cx.ptr, scope) } } impl DedicatedWorkerGlobalScope { pub fn run_worker_scope(worker_url: Url, + worker: TrustedWorkerAddress, resource_task: ResourceTask, receiver: Receiver, sender: ScriptChan) { @@ -84,13 +92,14 @@ impl DedicatedWorkerGlobalScope { let (_js_runtime, js_context) = ScriptTask::new_rt_and_cx(); let global = DedicatedWorkerGlobalScope::new( - worker_url, js_context.clone(), receiver, resource_task, + worker_url, worker, js_context.clone(), receiver, resource_task, sender).root(); match js_context.evaluate_script( global.reflector().get_jsobject(), source, url.serialize(), 1) { Ok(_) => (), Err(_) => println!("evaluate_script failed") } + global.delayed_release_worker(); let scope: &JSRef = WorkerGlobalScopeCast::from_ref(&*global); @@ -99,11 +108,15 @@ impl DedicatedWorkerGlobalScope { loop { match global.receiver.recv_opt() { Ok(DOMMessage(message)) => { - MessageEvent::dispatch(target, &Worker(*scope), message) + MessageEvent::dispatch(target, &Worker(*scope), message); + global.delayed_release_worker(); }, Ok(XHRProgressMsg(addr, progress)) => { XMLHttpRequest::handle_xhr_progress(addr, progress) }, + Ok(WorkerRelease(addr)) => { + Worker::handle_release(addr) + }, Ok(_) => fail!("Unexpected message"), Err(_) => break, } @@ -115,6 +128,19 @@ impl DedicatedWorkerGlobalScope { pub trait DedicatedWorkerGlobalScopeMethods { } +trait PrivateDedicatedWorkerGlobalScopeHelpers { + fn delayed_release_worker(&self); +} + +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(); + sender.send(WorkerRelease(*self.worker)); + } +} + impl Reflectable for DedicatedWorkerGlobalScope { fn reflector<'a>(&'a self) -> &'a Reflector { self.workerglobalscope.reflector() diff --git a/src/components/script/dom/worker.rs b/src/components/script/dom/worker.rs index 5007f212f9a..ff41b09e273 100644 --- a/src/components/script/dom/worker.rs +++ b/src/components/script/dom/worker.rs @@ -5,32 +5,43 @@ use dom::bindings::codegen::Bindings::WorkerBinding; use dom::bindings::codegen::Bindings::WorkerBinding::WorkerMethods; use dom::bindings::error::{Fallible, Syntax}; -use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::global::{GlobalRef, GlobalField}; +use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope; use dom::eventtarget::{EventTarget, WorkerTypeId}; use script_task::{ScriptChan, DOMMessage}; use servo_util::str::DOMString; + +use js::jsapi::{JS_AddObjectRoot, JS_RemoveObjectRoot}; use url::UrlParser; +use libc::c_void; +use std::cell::Cell; + +pub struct TrustedWorkerAddress(pub *const c_void); + #[deriving(Encodable)] pub struct Worker { eventtarget: EventTarget, + refcount: Cell, + global: GlobalField, sender: ScriptChan, } impl Worker { - pub fn new_inherited(sender: ScriptChan) -> Worker { + pub fn new_inherited(global: &GlobalRef, sender: ScriptChan) -> Worker { Worker { eventtarget: EventTarget::new_inherited(WorkerTypeId), + refcount: Cell::new(0), + global: GlobalField::from_rooted(global), sender: sender, } } pub fn new(global: &GlobalRef, sender: ScriptChan) -> Temporary { - reflect_dom_object(box Worker::new_inherited(sender), + reflect_dom_object(box Worker::new_inherited(global, sender), global, WorkerBinding::Wrap) } @@ -46,14 +57,52 @@ impl Worker { let resource_task = global.resource_task(); let (receiver, sender) = ScriptChan::new(); + + let worker = Worker::new(global, sender.clone()).root(); + let worker_ref = worker.addref(); + DedicatedWorkerGlobalScope::run_worker_scope( - worker_url, resource_task, receiver, sender.clone()); - Ok(Worker::new(global, sender)) + worker_url, worker_ref, resource_task, receiver, sender); + + Ok(Temporary::from_rooted(&*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, message: DOMString) { + self.addref(); let ScriptChan(ref sender) = self.sender; sender.send(DOMMessage(message)); } diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index ba6cd12c372..090cf38ee47 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -20,6 +20,7 @@ use dom::eventtarget::{EventTarget, EventTargetHelpers}; use dom::node; use dom::node::{ElementNodeTypeId, Node, NodeHelpers}; use dom::window::{TimerId, Window, WindowHelpers}; +use dom::worker::{Worker, TrustedWorkerAddress}; use dom::xmlhttprequest::{TrustedXHRAddress, XMLHttpRequest, XHRProgress}; use html::hubbub_html_parser::HtmlParserResult; use html::hubbub_html_parser::{HtmlDiscoveredStyle, HtmlDiscoveredScript}; @@ -86,6 +87,8 @@ pub enum ScriptMsg { /// Message sent through Worker.postMessage (only dispatched to /// DedicatedWorkerGlobalScope). DOMMessage(DOMString), + /// Releases one reference to the Worker object (dispatched to all tasks). + WorkerRelease(TrustedWorkerAddress), } /// Encapsulates internal communication within the script task. @@ -441,6 +444,7 @@ impl ScriptTask { FromConstellation(ResizeMsg(..)) => fail!("should have handled ResizeMsg already"), FromScript(XHRProgressMsg(addr, progress)) => XMLHttpRequest::handle_xhr_progress(addr, progress), FromScript(DOMMessage(..)) => fail!("unexpected message"), + FromScript(WorkerRelease(addr)) => Worker::handle_release(addr), } } From 82514dad6e11b4ef9fed334cbc554d8e782fe898 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 18 Jul 2014 12:24:15 +0200 Subject: [PATCH 3/4] Implement DedicatedWorkerGlobalScope.postMessage. --- .../script/dom/dedicatedworkerglobalscope.rs | 14 +++++++++++++- .../dom/webidls/DedicatedWorkerGlobalScope.webidl | 1 + src/components/script/dom/worker.rs | 10 ++++++++++ src/components/script/script_task.rs | 3 +++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/components/script/dom/dedicatedworkerglobalscope.rs b/src/components/script/dom/dedicatedworkerglobalscope.rs index 654183757f6..bf3888cced6 100644 --- a/src/components/script/dom/dedicatedworkerglobalscope.rs +++ b/src/components/script/dom/dedicatedworkerglobalscope.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::Bindings::DedicatedWorkerGlobalScopeBinding; +use dom::bindings::codegen::Bindings::DedicatedWorkerGlobalScopeBinding::DedicatedWorkerGlobalScopeMethods; use dom::bindings::codegen::InheritTypes::DedicatedWorkerGlobalScopeDerived; use dom::bindings::codegen::InheritTypes::{EventTargetCast, WorkerGlobalScopeCast}; use dom::bindings::global::Worker; @@ -18,9 +19,11 @@ use dom::workerglobalscope::WorkerGlobalScope; use dom::xmlhttprequest::XMLHttpRequest; use script_task::{ScriptTask, ScriptChan}; use script_task::{ScriptMsg, DOMMessage, XHRProgressMsg, WorkerRelease}; +use script_task::WorkerPostMessage; use script_task::StackRootTLS; use servo_net::resource_task::{ResourceTask, load_whole_resource}; +use servo_util::str::DOMString; use js::rust::Cx; @@ -114,6 +117,9 @@ impl DedicatedWorkerGlobalScope { Ok(XHRProgressMsg(addr, progress)) => { XMLHttpRequest::handle_xhr_progress(addr, progress) }, + Ok(WorkerPostMessage(addr, message)) => { + Worker::handle_message(addr, message); + }, Ok(WorkerRelease(addr)) => { Worker::handle_release(addr) }, @@ -125,7 +131,13 @@ impl DedicatedWorkerGlobalScope { } } -pub trait DedicatedWorkerGlobalScopeMethods { +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(); + sender.send(WorkerPostMessage(*self.worker, message)); + } } trait PrivateDedicatedWorkerGlobalScopeHelpers { diff --git a/src/components/script/dom/webidls/DedicatedWorkerGlobalScope.webidl b/src/components/script/dom/webidls/DedicatedWorkerGlobalScope.webidl index c0c69219e1e..d92b8a73911 100644 --- a/src/components/script/dom/webidls/DedicatedWorkerGlobalScope.webidl +++ b/src/components/script/dom/webidls/DedicatedWorkerGlobalScope.webidl @@ -6,5 +6,6 @@ [Global/*=Worker,DedicatedWorker*/] /*sealed*/ interface DedicatedWorkerGlobalScope : WorkerGlobalScope { //void postMessage(any message, optional sequence transfer); + void postMessage(DOMString message); // attribute EventHandler onmessage; }; diff --git a/src/components/script/dom/worker.rs b/src/components/script/dom/worker.rs index ff41b09e273..3b17375ee46 100644 --- a/src/components/script/dom/worker.rs +++ b/src/components/script/dom/worker.rs @@ -4,12 +4,14 @@ use dom::bindings::codegen::Bindings::WorkerBinding; use dom::bindings::codegen::Bindings::WorkerBinding::WorkerMethods; +use dom::bindings::codegen::InheritTypes::EventTargetCast; use dom::bindings::error::{Fallible, Syntax}; use dom::bindings::global::{GlobalRef, GlobalField}; use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope; use dom::eventtarget::{EventTarget, WorkerTypeId}; +use dom::messageevent::MessageEvent; use script_task::{ScriptChan, DOMMessage}; use servo_util::str::DOMString; @@ -66,6 +68,14 @@ impl Worker { Ok(Temporary::from_rooted(&*worker)) } + + pub fn handle_message(address: TrustedWorkerAddress, message: DOMString) { + let worker = unsafe { JS::from_trusted_worker_address(address).root() }; + + let target: &JSRef = EventTargetCast::from_ref(&*worker); + let global = worker.global.root(); + MessageEvent::dispatch(target, &global.root_ref(), message); + } } impl Worker { diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index 090cf38ee47..dd01017ff76 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -87,6 +87,8 @@ pub enum ScriptMsg { /// Message sent through Worker.postMessage (only dispatched to /// DedicatedWorkerGlobalScope). DOMMessage(DOMString), + /// Posts a message to the Worker object (dispatched to all tasks). + WorkerPostMessage(TrustedWorkerAddress, DOMString), /// Releases one reference to the Worker object (dispatched to all tasks). WorkerRelease(TrustedWorkerAddress), } @@ -444,6 +446,7 @@ impl ScriptTask { FromConstellation(ResizeMsg(..)) => fail!("should have handled ResizeMsg already"), FromScript(XHRProgressMsg(addr, progress)) => XMLHttpRequest::handle_xhr_progress(addr, progress), FromScript(DOMMessage(..)) => fail!("unexpected message"), + FromScript(WorkerPostMessage(addr, message)) => Worker::handle_message(addr, message), FromScript(WorkerRelease(addr)) => Worker::handle_release(addr), } } From bac9a3cf6da2932f6c24e50885a657e094c77686 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 12 Aug 2014 16:29:15 +0200 Subject: [PATCH 4/4] 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)) }