diff options
-rw-r--r-- | components/net_traits/lib.rs | 27 | ||||
-rw-r--r-- | components/script/dom/htmllinkelement.rs | 2 | ||||
-rw-r--r-- | components/script/dom/htmlmediaelement.rs | 2 | ||||
-rw-r--r-- | components/script/dom/htmlscriptelement.rs | 2 | ||||
-rw-r--r-- | components/script/dom/xmlhttprequest.rs | 2 | ||||
-rw-r--r-- | components/script/network_listener.rs | 27 | ||||
-rw-r--r-- | components/script/script_thread.rs | 2 |
7 files changed, 47 insertions, 17 deletions
diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index 127c85f13b0..4760797cc2f 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -187,6 +187,13 @@ pub trait FetchTaskTarget { fn process_response_eof(&mut self, response: &response::Response); } +pub trait FetchResponseListener { + fn process_request_body(&mut self); + fn process_request_eof(&mut self); + fn process_response(&mut self, metadata: Result<Metadata, NetworkError>); + fn process_response_eof(&mut self, response: Result<Vec<u8>, NetworkError>); +} + impl FetchTaskTarget for IpcSender<FetchResponseMsg> { fn process_request_body(&mut self, _: &request::Request) { let _ = self.send(FetchResponseMsg::ProcessRequestBody); @@ -217,6 +224,10 @@ impl FetchTaskTarget for IpcSender<FetchResponseMsg> { } } +pub trait Action<Listener> { + fn process(self, listener: &mut Listener); +} + /// A listener for asynchronous network events. Cancelling the underlying request is unsupported. pub trait AsyncResponseListener { /// The response headers for a request have been received. @@ -241,9 +252,9 @@ pub enum ResponseAction { ResponseComplete(Result<(), NetworkError>) } -impl ResponseAction { +impl<T: AsyncResponseListener> Action<T> for ResponseAction { /// Execute the default action on a provided listener. - pub fn process(self, listener: &mut AsyncResponseListener) { + fn process(self, listener: &mut T) { match self { ResponseAction::HeadersAvailable(m) => listener.headers_available(m), ResponseAction::DataAvailable(d) => listener.data_available(d), @@ -252,6 +263,18 @@ impl ResponseAction { } } +impl<T: FetchResponseListener> Action<T> for FetchResponseMsg { + /// Execute the default action on a provided listener. + fn process(self, listener: &mut T) { + match self { + FetchResponseMsg::ProcessRequestBody => listener.process_request_body(), + FetchResponseMsg::ProcessRequestEOF => listener.process_request_eof(), + FetchResponseMsg::ProcessResponse(meta) => listener.process_response(meta), + FetchResponseMsg::ProcessResponseEOF(data) => listener.process_response_eof(data), + } + } +} + /// A target for async networking events. Commonly used to dispatch a runnable event to another /// thread storing the wrapped closure for later execution. #[derive(Deserialize, Serialize)] diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index 2b0056a8d65..79b6ed32f0b 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -227,7 +227,7 @@ impl HTMLLinkElement { sender: action_sender, }; ROUTER.add_route(action_receiver.to_opaque(), box move |message| { - listener.notify(message.to().unwrap()); + listener.notify_action(message.to().unwrap()); }); if self.parser_inserted.get() { diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 7256ae1b131..70563ec95c7 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -484,7 +484,7 @@ impl HTMLMediaElement { sender: action_sender, }; ROUTER.add_route(action_receiver.to_opaque(), box move |message| { - listener.notify(message.to().unwrap()); + listener.notify_action(message.to().unwrap()); }); // FIXME: we're supposed to block the load event much earlier than now diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 1f9f49516dd..f280f670e4b 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -314,7 +314,7 @@ impl HTMLScriptElement { sender: action_sender, }; ROUTER.add_route(action_receiver.to_opaque(), box move |message| { - listener.notify(message.to().unwrap()); + listener.notify_action(message.to().unwrap()); }); doc.load_async(LoadType::Script(url), response_target); diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 318d3bbc1ec..3cb74ec282c 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -302,7 +302,7 @@ impl XMLHttpRequest { sender: action_sender, }; ROUTER.add_route(action_receiver.to_opaque(), box move |message| { - listener.notify(message.to().unwrap()); + listener.notify_action(message.to().unwrap()); }); core_resource_thread.send(Load(load_data, LoadConsumer::Listener(response_target), None)).unwrap(); } diff --git a/components/script/network_listener.rs b/components/script/network_listener.rs index cff0723d277..84561667f4f 100644 --- a/components/script/network_listener.rs +++ b/components/script/network_listener.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use net_traits::{AsyncResponseListener, ResponseAction}; +use net_traits::{Action, AsyncResponseListener, ResponseAction}; use script_runtime::ScriptThreadEventCategory::NetworkEvent; use script_runtime::{CommonScriptMsg, ScriptChan}; use script_thread::Runnable; @@ -10,13 +10,13 @@ use std::sync::{Arc, Mutex}; /// An off-thread sink for async network event runnables. All such events are forwarded to /// a target thread, where they are invoked on the provided context object. -pub struct NetworkListener<T: AsyncResponseListener + PreInvoke + Send + 'static> { - pub context: Arc<Mutex<T>>, +pub struct NetworkListener<Listener: PreInvoke + Send + 'static> { + pub context: Arc<Mutex<Listener>>, pub script_chan: Box<ScriptChan + Send>, } -impl<T: AsyncResponseListener + PreInvoke + Send + 'static> NetworkListener<T> { - pub fn notify(&self, action: ResponseAction) { +impl<Listener: PreInvoke + Send + 'static> NetworkListener<Listener> { + pub fn notify<A: Action<Listener>+Send+'static>(&self, action: A) { if let Err(err) = self.script_chan.send(CommonScriptMsg::RunnableMsg(NetworkEvent, box ListenerRunnable { context: self.context.clone(), action: action, @@ -26,6 +26,13 @@ impl<T: AsyncResponseListener + PreInvoke + Send + 'static> NetworkListener<T> { } } +// helps type inference +impl<Listener: AsyncResponseListener + PreInvoke + Send + 'static> NetworkListener<Listener> { + pub fn notify_action(&self, action: ResponseAction) { + self.notify(action); + } +} + /// A gating mechanism that runs before invoking the runnable on the target thread. /// If the `should_invoke` method returns false, the runnable is discarded without /// being invoked. @@ -36,13 +43,13 @@ pub trait PreInvoke { } /// A runnable for moving the async network events between threads. -struct ListenerRunnable<T: AsyncResponseListener + PreInvoke + Send> { - context: Arc<Mutex<T>>, - action: ResponseAction, +struct ListenerRunnable<A: Action<Listener>+Send+'static, Listener: PreInvoke + Send> { + context: Arc<Mutex<Listener>>, + action: A, } -impl<T: AsyncResponseListener + PreInvoke + Send> Runnable for ListenerRunnable<T> { - fn handler(self: Box<ListenerRunnable<T>>) { +impl<A: Action<Listener>+Send+'static, Listener: PreInvoke + Send> Runnable for ListenerRunnable<A, Listener> { + fn handler(self: Box<ListenerRunnable<A, Listener>>) { let this = *self; let mut context = this.context.lock().unwrap(); if context.should_invoke() { diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index eec1853239e..c4254af7eee 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -1947,7 +1947,7 @@ impl ScriptThread { script_chan: self.chan.clone(), }; ROUTER.add_route(action_receiver.to_opaque(), box move |message| { - listener.notify(message.to().unwrap()); + listener.notify_action(message.to().unwrap()); }); let response_target = AsyncResponseTarget { sender: action_sender, |