auto merge of #4474 : thiagopnts/servo/generic-msgs, r=jdm

This refs #3735. As discussed in the issue, I did it cloning when I couldn't dereference an attribute. The trait method should be on `&self` for object-safety reasons.
This commit is contained in:
bors-servo 2014-12-24 03:45:44 -07:00
commit 194ce20969
4 changed files with 43 additions and 21 deletions

View file

@ -19,7 +19,7 @@ use libc;
use std::ptr; use std::ptr;
/// DOM exceptions that can be thrown by a native DOM method. /// DOM exceptions that can be thrown by a native DOM method.
#[deriving(Show)] #[deriving(Show, Clone)]
pub enum Error { pub enum Error {
IndexSize, IndexSize,
FailureUnknown, FailureUnknown,

View file

@ -17,7 +17,6 @@ use dom::messageevent::MessageEvent;
use dom::worker::{Worker, TrustedWorkerAddress}; use dom::worker::{Worker, TrustedWorkerAddress};
use dom::workerglobalscope::{WorkerGlobalScope, WorkerGlobalScopeHelpers}; use dom::workerglobalscope::{WorkerGlobalScope, WorkerGlobalScopeHelpers};
use dom::workerglobalscope::WorkerGlobalScopeTypeId; use dom::workerglobalscope::WorkerGlobalScopeTypeId;
use dom::xmlhttprequest::XMLHttpRequest;
use script_task::{ScriptTask, ScriptChan, ScriptMsg, TimerSource}; use script_task::{ScriptTask, ScriptChan, ScriptMsg, TimerSource};
use script_task::StackRootTLS; use script_task::StackRootTLS;
@ -131,11 +130,8 @@ impl DedicatedWorkerGlobalScope {
MessageEvent::dispatch_jsval(target, GlobalRef::Worker(scope), message); MessageEvent::dispatch_jsval(target, GlobalRef::Worker(scope), message);
global.delayed_release_worker(); global.delayed_release_worker();
}, },
Ok(ScriptMsg::XHRProgress(addr, progress)) => { Ok(ScriptMsg::RunnableMsg(runnable)) => {
XMLHttpRequest::handle_progress(addr, progress) runnable.handler()
},
Ok(ScriptMsg::XHRRelease(addr)) => {
XMLHttpRequest::handle_release(addr)
}, },
Ok(ScriptMsg::WorkerPostMessage(addr, data, nbytes)) => { Ok(ScriptMsg::WorkerPostMessage(addr, data, nbytes)) => {
Worker::handle_message(addr, data, nbytes); Worker::handle_message(addr, data, nbytes);

View file

@ -25,7 +25,7 @@ use dom::urlsearchparams::URLSearchParamsHelpers;
use dom::xmlhttprequesteventtarget::XMLHttpRequestEventTarget; use dom::xmlhttprequesteventtarget::XMLHttpRequestEventTarget;
use dom::xmlhttprequesteventtarget::XMLHttpRequestEventTargetTypeId; use dom::xmlhttprequesteventtarget::XMLHttpRequestEventTargetTypeId;
use dom::xmlhttprequestupload::XMLHttpRequestUpload; use dom::xmlhttprequestupload::XMLHttpRequestUpload;
use script_task::{ScriptChan, ScriptMsg}; use script_task::{ScriptChan, ScriptMsg, Runnable};
use encoding::all::UTF_8; use encoding::all::UTF_8;
use encoding::label::encoding_from_whatwg_label; use encoding::label::encoding_from_whatwg_label;
@ -73,10 +73,37 @@ enum XMLHttpRequestState {
XHRDone = 4, // So as not to conflict with the ProgressMsg `Done` XHRDone = 4, // So as not to conflict with the ProgressMsg `Done`
} }
#[deriving(PartialEq)] struct XHRReleaseHandler(TrustedXHRAddress);
impl Runnable for XHRReleaseHandler {
fn handler(&self) {
let XHRReleaseHandler(addr) = *self;
XMLHttpRequest::handle_release(addr);
}
}
struct XHRProgressHandler {
addr: TrustedXHRAddress,
progress: XHRProgress,
}
impl XHRProgressHandler {
fn new(addr: TrustedXHRAddress, progress: XHRProgress) -> XHRProgressHandler {
XHRProgressHandler { addr: addr, progress: progress }
}
}
impl Runnable for XHRProgressHandler {
fn handler(&self) {
XMLHttpRequest::handle_progress(self.addr, self.progress.clone());
}
}
#[deriving(PartialEq, Clone)]
#[jstraceable] #[jstraceable]
pub struct GenerationId(uint); pub struct GenerationId(uint);
#[deriving(Clone)]
pub enum XHRProgress { pub enum XHRProgress {
/// Notify that headers have been received /// Notify that headers have been received
HeadersReceived(GenerationId, Option<Headers>, Option<RawStatus>), HeadersReceived(GenerationId, Option<Headers>, Option<RawStatus>),
@ -208,7 +235,7 @@ impl XMLHttpRequest {
}, },
SyncOrAsync::Async(addr, script_chan) => { SyncOrAsync::Async(addr, script_chan) => {
let ScriptChan(ref chan) = *script_chan; let ScriptChan(ref chan) = *script_chan;
chan.send(ScriptMsg::XHRProgress(addr, msg)); chan.send(ScriptMsg::RunnableMsg(box XHRProgressHandler::new(addr, msg)));
} }
} }
} }
@ -609,7 +636,7 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> {
self.fetch_time.set(time::now().to_timespec().sec); self.fetch_time.set(time::now().to_timespec().sec);
let script_chan = global.root_ref().script_chan().clone(); let script_chan = global.root_ref().script_chan().clone();
// Pin the object before launching the fetch task. // Pin the object before launching the fetch task.
// The `ScriptMsg::XHRRelease` sent when the fetch task completes will // The `ScriptMsg::RunnableMsg` sent when the fetch task completes will
// unpin it. This is to ensure that the object will stay alive // unpin it. This is to ensure that the object will stay alive
// as long as there are (possibly cancelled) inflight events queued up // as long as there are (possibly cancelled) inflight events queued up
// in the script task's port // in the script task's port
@ -625,7 +652,7 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> {
gen_id, gen_id,
start_port); start_port);
let ScriptChan(ref chan) = script_chan; let ScriptChan(ref chan) = script_chan;
chan.send(ScriptMsg::XHRRelease(addr)); chan.send(ScriptMsg::RunnableMsg(box XHRReleaseHandler(addr)));
}); });
let timeout = self.timeout.get(); let timeout = self.timeout.get();
if timeout > 0 { if timeout > 0 {

View file

@ -27,7 +27,6 @@ use dom::mouseevent::MouseEvent;
use dom::node::{mod, Node, NodeHelpers, NodeDamage, NodeTypeId}; use dom::node::{mod, Node, NodeHelpers, NodeDamage, NodeTypeId};
use dom::window::{Window, WindowHelpers}; use dom::window::{Window, WindowHelpers};
use dom::worker::{Worker, TrustedWorkerAddress}; use dom::worker::{Worker, TrustedWorkerAddress};
use dom::xmlhttprequest::{TrustedXHRAddress, XMLHttpRequest, XHRProgress};
use parse::html::{HTMLInput, parse_html}; use parse::html::{HTMLInput, parse_html};
use layout_interface::{ScriptLayoutChan, LayoutChan, ReflowGoal, ReflowQueryType}; use layout_interface::{ScriptLayoutChan, LayoutChan, ReflowGoal, ReflowQueryType};
use layout_interface; use layout_interface;
@ -87,6 +86,10 @@ pub enum TimerSource {
FromWorker FromWorker
} }
pub trait Runnable {
fn handler(&self);
}
/// Messages used to control script event loops, such as ScriptTask and /// Messages used to control script event loops, such as ScriptTask and
/// DedicatedWorkerGlobalScope. /// DedicatedWorkerGlobalScope.
pub enum ScriptMsg { pub enum ScriptMsg {
@ -106,10 +109,6 @@ pub enum ScriptMsg {
/// Notifies the script that a window associated with a particular pipeline /// Notifies the script that a window associated with a particular pipeline
/// should be closed (only dispatched to ScriptTask). /// should be closed (only dispatched to ScriptTask).
ExitWindow(PipelineId), ExitWindow(PipelineId),
/// Notifies the script of progress on a fetch (dispatched to all tasks).
XHRProgress(TrustedXHRAddress, XHRProgress),
/// Releases one reference to the XHR object (dispatched to all tasks).
XHRRelease(TrustedXHRAddress),
/// Message sent through Worker.postMessage (only dispatched to /// Message sent through Worker.postMessage (only dispatched to
/// DedicatedWorkerGlobalScope). /// DedicatedWorkerGlobalScope).
DOMMessage(*mut u64, size_t), DOMMessage(*mut u64, size_t),
@ -117,6 +116,8 @@ pub enum ScriptMsg {
WorkerPostMessage(TrustedWorkerAddress, *mut u64, size_t), WorkerPostMessage(TrustedWorkerAddress, *mut u64, size_t),
/// Releases one reference to the Worker object (dispatched to all tasks). /// Releases one reference to the Worker object (dispatched to all tasks).
WorkerRelease(TrustedWorkerAddress), WorkerRelease(TrustedWorkerAddress),
/// Generic message that encapsulates event handling.
RunnableMsg(Box<Runnable+Send>),
} }
/// Encapsulates internal communication within the script task. /// Encapsulates internal communication within the script task.
@ -572,16 +573,14 @@ impl ScriptTask {
self.handle_navigate_msg(direction), self.handle_navigate_msg(direction),
ScriptMsg::ExitWindow(id) => ScriptMsg::ExitWindow(id) =>
self.handle_exit_window_msg(id), self.handle_exit_window_msg(id),
ScriptMsg::XHRProgress(addr, progress) =>
XMLHttpRequest::handle_progress(addr, progress),
ScriptMsg::XHRRelease(addr) =>
XMLHttpRequest::handle_release(addr),
ScriptMsg::DOMMessage(..) => ScriptMsg::DOMMessage(..) =>
panic!("unexpected message"), panic!("unexpected message"),
ScriptMsg::WorkerPostMessage(addr, data, nbytes) => ScriptMsg::WorkerPostMessage(addr, data, nbytes) =>
Worker::handle_message(addr, data, nbytes), Worker::handle_message(addr, data, nbytes),
ScriptMsg::WorkerRelease(addr) => ScriptMsg::WorkerRelease(addr) =>
Worker::handle_release(addr), Worker::handle_release(addr),
ScriptMsg::RunnableMsg(runnable) =>
runnable.handler(),
} }
} }