mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
Give workers their own ScriptChan and use it for postMessage.
This ensures that XHR callbacks for XHR objects in workers are called on the worker thread rather than the main thread.
This commit is contained in:
parent
8e59706933
commit
96aad42a5d
3 changed files with 39 additions and 29 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,15 +44,23 @@ 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)
|
||||
|
||||
|
@ -75,7 +77,9 @@ pub enum ScriptMsg {
|
|||
/// Notifies the script that a window associated with a particular pipeline should be closed.
|
||||
ExitWindowMsg(PipelineId),
|
||||
/// Notifies the script of progress on a fetch
|
||||
XHRProgressMsg(TrustedXHRAddress, XHRProgress)
|
||||
XHRProgressMsg(TrustedXHRAddress, XHRProgress),
|
||||
/// Message sent through postMessage
|
||||
DOMMessage(DOMString),
|
||||
}
|
||||
|
||||
/// Encapsulates internal communication within the script task.
|
||||
|
@ -430,6 +434,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"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue