diff options
author | Ms2ger <ms2ger@gmail.com> | 2014-08-11 21:32:48 +0200 |
---|---|---|
committer | Ms2ger <ms2ger@gmail.com> | 2014-08-11 21:32:48 +0200 |
commit | aaa8982b60821629a9b312ff2bdd872db68feeb2 (patch) | |
tree | b2b999da62e2dc6e21de5a48d0070fc66c003858 | |
parent | 582119502e88aba60848b90f6ba5e977e7442d82 (diff) | |
parent | 034e815657fced9c3b31d48989be6316ee4f33a8 (diff) | |
download | servo-aaa8982b60821629a9b312ff2bdd872db68feeb2.tar.gz servo-aaa8982b60821629a9b312ff2bdd872db68feeb2.zip |
Merge pull request #3071 from Ms2ger/workers-threads
Give workers their own ScriptChan and use it for postMessage; r=Manishearth
-rw-r--r-- | src/components/script/dom/dedicatedworkerglobalscope.rs | 25 | ||||
-rw-r--r-- | src/components/script/dom/worker.rs | 18 | ||||
-rw-r--r-- | src/components/script/script_task.rs | 45 |
3 files changed, 52 insertions, 36 deletions
diff --git a/src/components/script/dom/dedicatedworkerglobalscope.rs b/src/components/script/dom/dedicatedworkerglobalscope.rs index 2aff963a8e0..f9e3210715e 100644 --- a/src/components/script/dom/dedicatedworkerglobalscope.rs +++ b/src/components/script/dom/dedicatedworkerglobalscope.rs @@ -14,11 +14,11 @@ use dom::eventtarget::WorkerGlobalScopeTypeId; use dom::messageevent::MessageEvent; use dom::workerglobalscope::DedicatedGlobalScope; use dom::workerglobalscope::WorkerGlobalScope; -use script_task::{ScriptTask, ScriptChan}; +use dom::xmlhttprequest::XMLHttpRequest; +use script_task::{ScriptTask, ScriptChan, ScriptMsg, DOMMessage, XHRProgressMsg}; use script_task::StackRootTLS; use servo_net::resource_task::{ResourceTask, load_whole_resource}; -use servo_util::str::DOMString; use js::rust::Cx; @@ -30,13 +30,13 @@ use url::Url; #[deriving(Encodable)] pub struct DedicatedWorkerGlobalScope { workerglobalscope: WorkerGlobalScope, - receiver: Untraceable<Receiver<DOMString>>, + receiver: Untraceable<Receiver<ScriptMsg>>, } impl DedicatedWorkerGlobalScope { pub fn new_inherited(worker_url: Url, cx: Rc<Cx>, - receiver: Receiver<DOMString>, + receiver: Receiver<ScriptMsg>, resource_task: ResourceTask, script_chan: ScriptChan) -> DedicatedWorkerGlobalScope { @@ -50,7 +50,7 @@ impl DedicatedWorkerGlobalScope { pub fn new(worker_url: Url, cx: Rc<Cx>, - receiver: Receiver<DOMString>, + receiver: Receiver<ScriptMsg>, resource_task: ResourceTask, script_chan: ScriptChan) -> Temporary<DedicatedWorkerGlobalScope> { @@ -62,9 +62,9 @@ impl DedicatedWorkerGlobalScope { impl DedicatedWorkerGlobalScope { pub fn run_worker_scope(worker_url: Url, - receiver: Receiver<DOMString>, - resource_task: ResourceTask, - script_chan: ScriptChan) { + resource_task: ResourceTask) -> ScriptChan { + let (receiver, sender) = ScriptChan::new(); + let sender_clone = sender.clone(); TaskBuilder::new() .native() .named(format!("Web Worker at {}", worker_url.serialize())) @@ -85,7 +85,7 @@ impl DedicatedWorkerGlobalScope { let (_js_runtime, js_context) = ScriptTask::new_rt_and_cx(); let global = DedicatedWorkerGlobalScope::new( worker_url, js_context.clone(), receiver, resource_task, - script_chan).root(); + sender).root(); match js_context.evaluate_script( global.reflector().get_jsobject(), source, url.serialize(), 1) { Ok(_) => (), @@ -98,13 +98,18 @@ impl DedicatedWorkerGlobalScope { EventTargetCast::from_ref(&*global); loop { match global.receiver.recv_opt() { - Ok(message) => { + Ok(DOMMessage(message)) => { MessageEvent::dispatch(target, &Worker(*scope), message) }, + Ok(XHRProgressMsg(addr, progress)) => { + XMLHttpRequest::handle_xhr_progress(addr, progress) + }, + Ok(_) => fail!("Unexpected message"), Err(_) => break, } } }); + return sender_clone; } } diff --git a/src/components/script/dom/worker.rs b/src/components/script/dom/worker.rs index 88a9b10307a..670ae7a5beb 100644 --- a/src/components/script/dom/worker.rs +++ b/src/components/script/dom/worker.rs @@ -7,10 +7,10 @@ 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::trace::Untraceable; 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 url::UrlParser; @@ -18,18 +18,18 @@ use url::UrlParser; #[deriving(Encodable)] pub struct Worker { eventtarget: EventTarget, - sender: Untraceable<Sender<DOMString>>, + sender: ScriptChan, } impl Worker { - pub fn new_inherited(sender: Sender<DOMString>) -> Worker { + pub fn new_inherited(sender: ScriptChan) -> Worker { Worker { eventtarget: EventTarget::new_inherited(WorkerTypeId), - sender: Untraceable::new(sender), + sender: sender, } } - pub fn new(global: &GlobalRef, sender: Sender<DOMString>) -> Temporary<Worker> { + pub fn new(global: &GlobalRef, sender: ScriptChan) -> Temporary<Worker> { reflect_dom_object(box Worker::new_inherited(sender), global, WorkerBinding::Wrap) @@ -44,17 +44,17 @@ impl Worker { Err(_) => return Err(Syntax), }; - let (sender, receiver) = channel(); let resource_task = global.resource_task(); - DedicatedWorkerGlobalScope::run_worker_scope( - worker_url, receiver, resource_task, global.script_chan().clone()); + let sender = DedicatedWorkerGlobalScope::run_worker_scope( + worker_url, resource_task); Ok(Worker::new(global, sender)) } } impl<'a> WorkerMethods for JSRef<'a, Worker> { fn PostMessage(&self, message: DOMString) { - self.sender.send(message); + 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 2f7df8d6ddd..ba6cd12c372 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -31,12 +31,6 @@ use layout_interface::ContentChangedDocumentDamage; use layout_interface; use page::{Page, IterablePage, Frame}; -use geom::point::Point2D; -use js::jsapi::{JS_SetWrapObjectCallbacks, JS_SetGCZeal, JS_DEFAULT_ZEAL_FREQ, JS_GC}; -use js::jsapi::{JSContext, JSRuntime}; -use js::rust::{Cx, RtUtils}; -use js::rust::with_compartment; -use js; use script_traits::{CompositorEvent, ResizeEvent, ReflowEvent, ClickEvent, MouseDownEvent}; use script_traits::{MouseMoveEvent, MouseUpEvent, ConstellationControlMsg, ScriptTaskFactory}; use script_traits::{ResizeMsg, AttachLayoutMsg, LoadMsg, SendEventMsg, ResizeInactiveMsg}; @@ -50,32 +44,48 @@ use servo_msg::constellation_msg; use servo_net::image_cache_task::ImageCacheTask; use servo_net::resource_task::ResourceTask; use servo_util::geometry::to_frac_px; +use servo_util::str::DOMString; use servo_util::task::spawn_named_with_send_on_failure; + +use geom::point::Point2D; +use js::jsapi::{JS_SetWrapObjectCallbacks, JS_SetGCZeal, JS_DEFAULT_ZEAL_FREQ, JS_GC}; +use js::jsapi::{JSContext, JSRuntime}; +use js::rust::{Cx, RtUtils}; +use js::rust::with_compartment; +use js; +use url::Url; + +use serialize::{Encoder, Encodable}; use std::any::{Any, AnyRefExt}; use std::cell::RefCell; use std::comm::{channel, Sender, Receiver, Select}; use std::mem::replace; use std::rc::Rc; -use url::Url; - -use serialize::{Encoder, Encodable}; local_data_key!(pub StackRoots: *const RootCollection) -/// Messages used to control the script task. +/// Messages used to control script event loops, such as ScriptTask and +/// DedicatedWorkerGlobalScope. pub enum ScriptMsg { - /// Acts on a fragment URL load on the specified pipeline. + /// Acts on a fragment URL load on the specified pipeline (only dispatched + /// to ScriptTask). TriggerFragmentMsg(PipelineId, Url), - /// Begins a content-initiated load on the specified pipeline. + /// Begins a content-initiated load on the specified pipeline (only + /// dispatched to ScriptTask). TriggerLoadMsg(PipelineId, Url), - /// Instructs the script task to send a navigate message to the constellation. + /// Instructs the script task to send a navigate message to + /// the constellation (only dispatched to ScriptTask). NavigateMsg(NavigationDirection), - /// Fires a JavaScript timeout. + /// Fires a JavaScript timeout (only dispatched to ScriptTask). FireTimerMsg(PipelineId, TimerId), - /// Notifies the script that a window associated with a particular pipeline should be closed. + /// Notifies the script that a window associated with a particular pipeline + /// should be closed (only dispatched to ScriptTask). ExitWindowMsg(PipelineId), - /// Notifies the script of progress on a fetch - XHRProgressMsg(TrustedXHRAddress, XHRProgress) + /// Notifies the script of progress on a fetch (dispatched to all tasks). + XHRProgressMsg(TrustedXHRAddress, XHRProgress), + /// Message sent through Worker.postMessage (only dispatched to + /// DedicatedWorkerGlobalScope). + DOMMessage(DOMString), } /// Encapsulates internal communication within the script task. @@ -430,6 +440,7 @@ impl ScriptTask { FromScript(ExitWindowMsg(id)) => self.handle_exit_window_msg(id), FromConstellation(ResizeMsg(..)) => fail!("should have handled ResizeMsg already"), FromScript(XHRProgressMsg(addr, progress)) => XMLHttpRequest::handle_xhr_progress(addr, progress), + FromScript(DOMMessage(..)) => fail!("unexpected message"), } } |