diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml index 6d75015d7b3..e3ec5f2ed24 100644 --- a/components/compositing/Cargo.toml +++ b/components/compositing/Cargo.toml @@ -66,10 +66,13 @@ git = "https://github.com/pcwalton/ipc-channel" git = "https://github.com/ecoal95/rust-offscreen-rendering-context" features = ["texture_surface"] +[dependencies.url] +version = "0.2" +features = [ "serde_serialization" ] + [dependencies] log = "0.3" num = "0.1.24" -url = "0.2.36" time = "0.1.17" libc = "0.1" gleam = "0.1" @@ -80,3 +83,4 @@ core-graphics = "0.1" [target.x86_64-apple-darwin.dependencies.core-text] git = "https://github.com/servo/core-text-rs" + diff --git a/components/gfx/Cargo.toml b/components/gfx/Cargo.toml index 1e7894b86b0..9ec80d3e091 100644 --- a/components/gfx/Cargo.toml +++ b/components/gfx/Cargo.toml @@ -47,10 +47,13 @@ path = "../script_traits" [dependencies.ipc-channel] git = "https://github.com/pcwalton/ipc-channel" +[dependencies.url] +version = "0.2" +features = [ "serde_serialization" ] + [dependencies] log = "0.3" fnv = "1.0" -url = "0.2.36" time = "0.1.12" bitflags = "0.3" rustc-serialize = "0.3" diff --git a/components/layout/Cargo.toml b/components/layout/Cargo.toml index 314b3da4b72..d1ed4e112ad 100644 --- a/components/layout/Cargo.toml +++ b/components/layout/Cargo.toml @@ -62,11 +62,14 @@ features = [ "serde-serialization" ] [dependencies.ipc-channel] git = "https://github.com/pcwalton/ipc-channel" +[dependencies.url] +version = "0.2" +features = [ "serde_serialization" ] + [dependencies] log = "0.3" encoding = "0.2" fnv = "1.0" -url = "0.2.36" bitflags = "0.3" rustc-serialize = "0.3" libc = "0.1" diff --git a/components/layout_traits/Cargo.toml b/components/layout_traits/Cargo.toml index f92fc5bb657..355a5ddc265 100644 --- a/components/layout_traits/Cargo.toml +++ b/components/layout_traits/Cargo.toml @@ -28,8 +28,11 @@ path = "../util" [dependencies.ipc-channel] git = "https://github.com/pcwalton/ipc-channel" +[dependencies.url] +version = "0.2" +features = [ "serde_serialization" ] + [dependencies] -url = "0.2.36" euclid = "0.1" serde = "0.4" serde_macros = "0.4" diff --git a/components/net/Cargo.toml b/components/net/Cargo.toml index a76178f0085..3d304658b1e 100644 --- a/components/net/Cargo.toml +++ b/components/net/Cargo.toml @@ -27,9 +27,12 @@ features = [ "serde-serialization" ] [dependencies.ipc-channel] git = "https://github.com/pcwalton/ipc-channel" +[dependencies.url] +version = "0.2" +features = [ "serde_serialization" ] + [dependencies] log = "0.3" -url = "0.2.36" time = "0.1.17" openssl="0.6.1" rustc-serialize = "0.3" @@ -39,3 +42,4 @@ regex_macros = "0.1.8" flate2 = "0.2.0" uuid = "0.1.16" euclid = "0.1" + diff --git a/components/net/about_loader.rs b/components/net/about_loader.rs index 213988904c2..aab22f1a2f9 100644 --- a/components/net/about_loader.rs +++ b/components/net/about_loader.rs @@ -39,7 +39,8 @@ pub fn factory(mut load_data: LoadData, start_chan: LoadConsumer, classifier: Ar } _ => { start_sending(start_chan, Metadata::default(load_data.url)) - .send(Done(Err("Unknown about: URL.".to_string()))).unwrap(); + .send(Done(Err("Unknown about: URL.".to_string()))) + .unwrap(); return } }; diff --git a/components/net/data_loader.rs b/components/net/data_loader.rs index 36daf044e61..d4bad86a412 100644 --- a/components/net/data_loader.rs +++ b/components/net/data_loader.rs @@ -34,15 +34,16 @@ pub fn load(load_data: LoadData, start_chan: LoadConsumer) { _ => panic!("Expected a non-relative scheme URL.") }; match url.query { - Some(query) => { + Some(ref query) => { scheme_data.push_str("?"); - scheme_data.push_str(&query); + scheme_data.push_str(query); }, None => () } let parts: Vec<&str> = scheme_data.splitn(2, ',').collect(); if parts.len() != 2 { - start_sending(start_chan, metadata).send(Done(Err("invalid data uri".to_string()))).unwrap(); + start_sending(start_chan, + metadata).send(Done(Err("invalid data uri".to_string()))).unwrap(); return; } diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index 637558a4e7f..d5e75bc2e1b 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -9,6 +9,7 @@ use mime_classifier::MIMEClassifier; use resource_task::{start_sending_opt, start_sending_sniffed_opt}; use hsts::{HSTSList, secure_url}; +use ipc_channel::ipc::{self, IpcSender}; use log; use std::collections::HashSet; use file_loader; @@ -36,7 +37,7 @@ use uuid; use std::borrow::ToOwned; use std::boxed::FnBox; -pub fn factory(cookies_chan: Sender, +pub fn factory(cookies_chan: IpcSender, devtools_chan: Option>, hsts_list: Arc>) -> Box) + Send> { @@ -86,7 +87,7 @@ fn request_must_be_secured(hsts_list: &HSTSList, url: &Url) -> bool { fn load(mut load_data: LoadData, start_chan: LoadConsumer, classifier: Arc, - cookies_chan: Sender, + cookies_chan: IpcSender, devtools_chan: Option>, hsts_list: Arc>) { // FIXME: At the time of writing this FIXME, servo didn't have any central @@ -153,6 +154,7 @@ reason: \"certificate verify failed\" }]))"; Request::with_connector(load_data.method.clone(), url.clone(), &HttpsConnector::new(Openssl { context: Arc::new(context) })) }; + let mut req = match req { Ok(req) => req, Err(HttpError::Io(ref io_error)) if ( @@ -201,8 +203,10 @@ reason: \"certificate verify failed\" }]))"; req.headers_mut().set(accept); } - let (tx, rx) = channel(); - cookies_chan.send(ControlMsg::GetCookiesForUrl(url.clone(), tx, CookieSource::HTTP)).unwrap(); + let (tx, rx) = ipc::channel().unwrap(); + cookies_chan.send(ControlMsg::GetCookiesForUrl(url.clone(), + tx, + CookieSource::HTTP)).unwrap(); if let Some(cookie_list) = rx.recv().unwrap() { let mut v = Vec::new(); v.push(cookie_list.into_bytes()); diff --git a/components/net/image_cache_task.rs b/components/net/image_cache_task.rs index e6088051c29..7c672b1e604 100644 --- a/components/net/image_cache_task.rs +++ b/components/net/image_cache_task.rs @@ -97,20 +97,6 @@ struct ResourceLoadInfo { url: Url, } -struct ResourceListener { - url: Url, - sender: Sender, -} - -impl AsyncResponseTarget for ResourceListener { - fn invoke_with_listener(&self, action: ResponseAction) { - self.sender.send(ResourceLoadInfo { - action: action, - url: self.url.clone(), - }).unwrap(); - } -} - /// Implementation of the image cache struct ImageCache { // Receive commands from clients @@ -330,11 +316,20 @@ impl ImageCache { e.insert(pending_load); let load_data = LoadData::new(url.clone(), None); - let listener = box ResourceListener { - url: url, - sender: self.progress_sender.clone(), + let (action_sender, action_receiver) = ipc::channel().unwrap(); + let response_target = AsyncResponseTarget { + sender: action_sender, }; - let msg = ControlMsg::Load(load_data, LoadConsumer::Listener(listener)); + let msg = ControlMsg::Load(load_data, + LoadConsumer::Listener(response_target)); + let progress_sender = self.progress_sender.clone(); + ROUTER.add_route(action_receiver.to_opaque(), box move |message| { + let action: ResponseAction = message.to().unwrap(); + progress_sender.send(ResourceLoadInfo { + action: action, + url: url.clone(), + }).unwrap(); + }); self.resource_task.send(msg).unwrap(); } } diff --git a/components/net/resource_task.rs b/components/net/resource_task.rs index 1e857102e33..1ccd09d6219 100644 --- a/components/net/resource_task.rs +++ b/components/net/resource_task.rs @@ -12,8 +12,8 @@ use cookie_storage::CookieStorage; use cookie; use mime_classifier::MIMEClassifier; -use net_traits::{ControlMsg, LoadData, LoadResponse, LoadConsumer}; -use net_traits::{Metadata, ProgressMsg, ResourceTask, AsyncResponseTarget, ResponseAction, CookieSource}; +use net_traits::{ControlMsg, LoadData, LoadResponse, LoadConsumer, CookieSource}; +use net_traits::{Metadata, ProgressMsg, ResourceTask, AsyncResponseTarget, ResponseAction}; use net_traits::ProgressMsg::Done; use util::opts; use util::task::spawn_named; @@ -24,6 +24,7 @@ use hsts::{HSTSList, HSTSEntry, preload_hsts_domains}; use devtools_traits::{DevtoolsControlMsg}; use hyper::header::{ContentType, Header, SetCookie, UserAgent}; use hyper::mime::{Mime, TopLevel, SubLevel}; +use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use regex::Regex; use std::borrow::ToOwned; @@ -34,7 +35,7 @@ use std::fs::File; use std::io::{BufReader, Read}; use std::sync::Arc; use std::sync::Mutex; -use std::sync::mpsc::{channel, Receiver, Sender}; +use std::sync::mpsc::{channel, Sender}; static mut HOST_TABLE: Option<*mut HashMap> = None; pub static IPV4_REGEX: Regex = regex!( @@ -67,8 +68,8 @@ pub fn global_init() { } pub enum ProgressSender { - Channel(Sender), - Listener(Box), + Channel(IpcSender), + Listener(AsyncResponseTarget), } impl ProgressSender { @@ -124,7 +125,8 @@ pub fn start_sending_sniffed_opt(start_chan: LoadConsumer, mut metadata: Metadat } } - let supplied_type = metadata.content_type.map(|ContentType(Mime(toplevel, sublevel, _))| { + let supplied_type = + metadata.content_type.map(|ContentType(Mime(toplevel, sublevel, _))| { (format!("{}", toplevel), format!("{}", sublevel)) }); metadata.content_type = classifier.classify(nosniff, check_for_apache_bug, &supplied_type, @@ -143,7 +145,7 @@ pub fn start_sending_sniffed_opt(start_chan: LoadConsumer, mut metadata: Metadat pub fn start_sending_opt(start_chan: LoadConsumer, metadata: Metadata) -> Result { match start_chan { LoadConsumer::Channel(start_chan) => { - let (progress_chan, progress_port) = channel(); + let (progress_chan, progress_port) = ipc::channel().unwrap(); let result = start_chan.send(LoadResponse { metadata: metadata, progress_port: progress_port, @@ -168,7 +170,7 @@ pub fn new_resource_task(user_agent: Option, None => HSTSList::new() }; - let (setup_chan, setup_port) = channel(); + let (setup_chan, setup_port) = ipc::channel().unwrap(); let setup_chan_clone = setup_chan.clone(); spawn_named("ResourceManager".to_owned(), move || { let resource_manager = ResourceManager::new( @@ -218,7 +220,7 @@ pub fn replace_hosts(mut load_data: LoadData, host_table: *mut HashMap, + from_client: IpcReceiver, resource_manager: ResourceManager } @@ -251,8 +253,7 @@ impl ResourceChannelManager { pub struct ResourceManager { user_agent: Option, cookie_storage: CookieStorage, - // TODO: Can this be de-coupled? - resource_task: Sender, + resource_task: IpcSender, mime_classifier: Arc, devtools_chan: Option>, hsts_list: Arc> @@ -260,9 +261,9 @@ pub struct ResourceManager { impl ResourceManager { pub fn new(user_agent: Option, - resource_task: Sender, - hsts_list: HSTSList, - devtools_channel: Option>) -> ResourceManager { + resource_task: IpcSender, + hsts_list: HSTSList, + devtools_channel: Option>) -> ResourceManager { ResourceManager { user_agent: user_agent, cookie_storage: CookieStorage::new(), @@ -274,7 +275,6 @@ impl ResourceManager { } } - impl ResourceManager { fn set_cookies_for_url(&mut self, request: Url, cookie_list: String, source: CookieSource) { let header = Header::parse_header(&[cookie_list.into_bytes()]); diff --git a/components/net_traits/Cargo.toml b/components/net_traits/Cargo.toml index c3999b25fc9..5ca00f82ce5 100644 --- a/components/net_traits/Cargo.toml +++ b/components/net_traits/Cargo.toml @@ -24,13 +24,13 @@ git = "https://github.com/servo/rust-stb-image" version = "0.6" features = [ "serde-serialization" ] -[dependencies.url] -version = "0.2.36" -features = [ "serde_serialization" ] - [dependencies.ipc-channel] git = "https://github.com/pcwalton/ipc-channel" +[dependencies.url] +version = "0.2" +features = [ "serde_serialization" ] + [dependencies] log = "0.3" euclid = "0.1" diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index 0028c61dcce..05837ec5054 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -10,8 +10,6 @@ #![feature(vec_push_all)] #![plugin(serde_macros)] -#![plugin(serde_macros)] - extern crate euclid; extern crate hyper; extern crate ipc_channel; @@ -28,10 +26,11 @@ use hyper::header::{ContentType, Headers}; use hyper::http::RawStatus; use hyper::method::Method; use hyper::mime::{Mime, Attr}; +use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use msg::constellation_msg::{PipelineId}; +use serde::{Deserializer, Serializer}; use url::Url; -use std::sync::mpsc::{channel, Receiver, Sender}; use std::thread; pub mod image_cache_task; @@ -46,7 +45,7 @@ pub mod image { pub mod base; } -#[derive(Clone)] +#[derive(Clone, Deserialize, Serialize)] pub struct LoadData { pub url: Url, pub method: Method, @@ -87,6 +86,7 @@ pub trait AsyncResponseListener { /// Data for passing between threads/processes to indicate a particular action to /// take on a provided network listener. +#[derive(Deserialize, Serialize)] pub enum ResponseAction { /// Invoke headers_available HeadersAvailable(Metadata), @@ -109,32 +109,41 @@ impl ResponseAction { /// A target for async networking events. Commonly used to dispatch a runnable event to another /// thread storing the wrapped closure for later execution. -pub trait AsyncResponseTarget { - fn invoke_with_listener(&self, action: ResponseAction); +#[derive(Deserialize, Serialize)] +pub struct AsyncResponseTarget { + pub sender: IpcSender, +} + +impl AsyncResponseTarget { + pub fn invoke_with_listener(&self, action: ResponseAction) { + self.sender.send(action).unwrap() + } } /// A wrapper for a network load that can either be channel or event-based. +#[derive(Deserialize, Serialize)] pub enum LoadConsumer { - Channel(Sender), - Listener(Box), + Channel(IpcSender), + Listener(AsyncResponseTarget), } /// Handle to a resource task -pub type ResourceTask = Sender; +pub type ResourceTask = IpcSender; -#[derive(PartialEq, Copy, Clone)] +#[derive(PartialEq, Copy, Clone, Deserialize, Serialize)] pub enum IncludeSubdomains { Included, NotIncluded } +#[derive(Deserialize, Serialize)] pub enum ControlMsg { /// Request the data associated with a particular URL Load(LoadData, LoadConsumer), /// Store a set of cookies for a given originating URL SetCookiesForUrl(Url, String, CookieSource), /// Retrieve the stored cookies for a given URL - GetCookiesForUrl(Url, Sender>, CookieSource), + GetCookiesForUrl(Url, IpcSender>, CookieSource), /// Store a domain's STS information SetHSTSEntryForHost(String, IncludeSubdomains, Option), Exit @@ -180,17 +189,17 @@ impl PendingAsyncLoad { } /// Initiate the network request associated with this pending load. - pub fn load(mut self) -> Receiver { + pub fn load(mut self) -> IpcReceiver { self.guard.neuter(); let load_data = LoadData::new(self.url, self.pipeline); - let (sender, receiver) = channel(); + let (sender, receiver) = ipc::channel().unwrap(); let consumer = LoadConsumer::Channel(sender); self.resource_task.send(ControlMsg::Load(load_data, consumer)).unwrap(); receiver } /// Initiate the network request associated with this pending load, using the provided target. - pub fn load_async(mut self, listener: Box) { + pub fn load_async(mut self, listener: AsyncResponseTarget) { self.guard.neuter(); let load_data = LoadData::new(self.url, self.pipeline); let consumer = LoadConsumer::Listener(listener); @@ -203,23 +212,24 @@ impl PendingAsyncLoad { /// /// Even if loading fails immediately, we send one of these and the /// progress_port will provide the error. +#[derive(Serialize, Deserialize)] pub struct LoadResponse { /// Metadata, such as from HTTP headers. pub metadata: Metadata, /// Port for reading data. - pub progress_port: Receiver, + pub progress_port: IpcReceiver, } -#[derive(Clone)] +#[derive(Clone, Deserialize, Serialize)] pub struct ResourceCORSData { /// CORS Preflight flag pub preflight: bool, /// Origin of CORS Request - pub origin: Url + pub origin: Url, } /// Metadata about a loaded resource, such as is obtained from HTTP headers. -#[derive(Clone)] +#[derive(Clone, Deserialize, Serialize)] pub struct Metadata { /// Final URL after redirects. pub final_url: Url, @@ -268,7 +278,7 @@ impl Metadata { } /// The creator of a given cookie -#[derive(PartialEq, Copy, Clone)] +#[derive(PartialEq, Copy, Clone, Deserialize, Serialize)] pub enum CookieSource { /// An HTTP API HTTP, @@ -277,7 +287,7 @@ pub enum CookieSource { } /// Messages sent in response to a `Load` message -#[derive(PartialEq,Debug)] +#[derive(PartialEq, Debug, Deserialize, Serialize)] pub enum ProgressMsg { /// Binary data - there may be multiple of these Payload(Vec), @@ -288,16 +298,17 @@ pub enum ProgressMsg { /// Convenience function for synchronously loading a whole resource. pub fn load_whole_resource(resource_task: &ResourceTask, url: Url) -> Result<(Metadata, Vec), String> { - let (start_chan, start_port) = channel(); - resource_task.send(ControlMsg::Load(LoadData::new(url, None), LoadConsumer::Channel(start_chan))).unwrap(); + let (start_chan, start_port) = ipc::channel().unwrap(); + resource_task.send(ControlMsg::Load(LoadData::new(url, None), + LoadConsumer::Channel(start_chan))).unwrap(); let response = start_port.recv().unwrap(); let mut buf = vec!(); loop { match response.progress_port.recv().unwrap() { ProgressMsg::Payload(data) => buf.push_all(&data), - ProgressMsg::Done(Ok(())) => return Ok((response.metadata, buf)), - ProgressMsg::Done(Err(e)) => return Err(e) + ProgressMsg::Done(Ok(())) => return Ok((response.metadata, buf)), + ProgressMsg::Done(Err(e)) => return Err(e) } } } @@ -306,13 +317,15 @@ pub fn load_whole_resource(resource_task: &ResourceTask, url: Url) pub fn load_bytes_iter(pending: PendingAsyncLoad) -> (Metadata, ProgressMsgPortIterator) { let input_port = pending.load(); let response = input_port.recv().unwrap(); - let iter = ProgressMsgPortIterator { progress_port: response.progress_port }; + let iter = ProgressMsgPortIterator { + progress_port: response.progress_port + }; (response.metadata, iter) } /// Iterator that reads chunks of bytes from a ProgressMsg port pub struct ProgressMsgPortIterator { - progress_port: Receiver + progress_port: IpcReceiver, } impl Iterator for ProgressMsgPortIterator { @@ -330,4 +343,3 @@ impl Iterator for ProgressMsgPortIterator { } } - diff --git a/components/profile_traits/Cargo.toml b/components/profile_traits/Cargo.toml index f85223c99ee..6cdf18b2b38 100644 --- a/components/profile_traits/Cargo.toml +++ b/components/profile_traits/Cargo.toml @@ -10,9 +10,12 @@ path = "lib.rs" [dependencies.ipc-channel] git = "https://github.com/pcwalton/ipc-channel" +[dependencies.url] +version = "0.2" +features = [ "serde_serialization" ] + [dependencies] serde = "0.4" serde_macros = "0.4" time = "0.1.12" -url = "0.2.36" diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index f079fafe1ab..97ecdb8e70a 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -76,7 +76,7 @@ rustc-serialize = "0.3" libc = "0.1" unicase = "0.1" num = "0.1.24" -websocket = "0.12" +websocket = "0.12.0" uuid = "0.1.16" smallvec = "0.1" html5ever = { version = "0.2.1", features = ["unstable"] } diff --git a/components/script/cors.rs b/components/script/cors.rs index c5a99fac63d..b1a1e56cb02 100644 --- a/components/script/cors.rs +++ b/components/script/cors.rs @@ -11,7 +11,7 @@ use network_listener::{NetworkListener, PreInvoke}; use script_task::ScriptChan; -use net_traits::{AsyncResponseTarget, AsyncResponseListener, ResponseAction, Metadata}; +use net_traits::{AsyncResponseListener, ResponseAction, Metadata}; use std::ascii::AsciiExt; use std::borrow::ToOwned; @@ -144,7 +144,7 @@ impl CORSRequest { let mut context = listener.context.lock(); let context = context.as_mut().unwrap(); *context.response.borrow_mut() = Some(response); - listener.invoke_with_listener(ResponseAction::ResponseComplete(Ok(()))); + listener.notify(ResponseAction::ResponseComplete(Ok(()))); }); } diff --git a/components/script/document_loader.rs b/components/script/document_loader.rs index a59b4895b9e..56ee98bdbbf 100644 --- a/components/script/document_loader.rs +++ b/components/script/document_loader.rs @@ -9,6 +9,7 @@ use script_task::{ScriptMsg, ScriptChan}; use msg::constellation_msg::{PipelineId}; use net_traits::{Metadata, load_whole_resource, ResourceTask, PendingAsyncLoad}; use net_traits::AsyncResponseTarget; +use std::sync::Arc; use url::Url; #[derive(JSTraceable, PartialEq, Clone, Debug)] @@ -34,7 +35,9 @@ impl LoadType { #[derive(JSTraceable)] pub struct DocumentLoader { - pub resource_task: ResourceTask, + /// We use an `Arc` here in order to avoid file descriptor exhaustion when there + /// are lots of iframes. + pub resource_task: Arc, notifier_data: Option, blocking_loads: Vec, } @@ -50,7 +53,9 @@ impl DocumentLoader { DocumentLoader::new_with_task(existing.resource_task.clone(), None, None) } - pub fn new_with_task(resource_task: ResourceTask, + /// We use an `Arc` here in order to avoid file descriptor exhaustion when there + /// are lots of iframes. + pub fn new_with_task(resource_task: Arc, data: Option, initial_load: Option,) -> DocumentLoader { @@ -69,11 +74,11 @@ impl DocumentLoader { let url = load.url().clone(); self.blocking_loads.push(load); let pipeline = self.notifier_data.as_ref().map(|data| data.pipeline); - PendingAsyncLoad::new(self.resource_task.clone(), url, pipeline) + PendingAsyncLoad::new((*self.resource_task).clone(), url, pipeline) } /// Create and initiate a new network request. - pub fn load_async(&mut self, load: LoadType, listener: Box) { + pub fn load_async(&mut self, load: LoadType, listener: AsyncResponseTarget) { let pending = self.prepare_async_load(load); pending.load_async(listener) } diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs index 5f0f7668af4..cfdd3df4af5 100644 --- a/components/script/dom/bindings/global.rs +++ b/components/script/dom/bindings/global.rs @@ -116,7 +116,7 @@ impl<'a> GlobalRef<'a> { let doc = window.Document(); let doc = doc.r(); let loader = doc.loader(); - loader.resource_task.clone() + (*loader.resource_task).clone() } GlobalRef::Worker(ref worker) => worker.resource_task().clone(), } diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 741921af652..770515cce40 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -45,7 +45,7 @@ use euclid::size::Size2D; use html5ever::tree_builder::QuirksMode; use hyper::header::Headers; use hyper::method::Method; -use ipc_channel::ipc::IpcSender; +use ipc_channel::ipc::{IpcReceiver, IpcSender}; use js::jsapi::{JSObject, JSTracer, JSGCTraceKind, JS_CallValueTracer, JS_CallObjectTracer, GCTraceKindToAscii, Heap}; use js::jsapi::JS_CallUnbarrieredObjectTracer; use js::jsval::JSVal; @@ -57,6 +57,7 @@ use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask}; use net_traits::storage_task::StorageType; use script_traits::ScriptControlChan; use script_traits::UntrustedNodeAddress; +use serde::{Serialize, Deserialize}; use smallvec::SmallVec; use msg::compositor_msg::ScriptListener; use msg::constellation_msg::ConstellationChan; @@ -64,7 +65,6 @@ use net_traits::image::base::Image; use profile_traits::mem::ProfilerChan; use util::str::{LengthOrPercentageOrAuto}; use selectors::parser::PseudoElement; -use serde::{Deserialize, Serialize}; use std::cell::{Cell, UnsafeCell, RefCell}; use std::collections::{HashMap, HashSet}; use std::collections::hash_state::HashState; @@ -358,7 +358,15 @@ impl JSTraceable for Box { impl JSTraceable for () { #[inline] - fn trace(&self, _trc: *mut JSTracer) { + fn trace(&self, _: *mut JSTracer) { + // Do nothing + } +} + +impl JSTraceable for IpcReceiver where T: Deserialize + Serialize { + #[inline] + fn trace(&self, _: *mut JSTracer) { + // Do nothing } } diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index 63a5a82a46c..5c44f5aff6a 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -181,8 +181,8 @@ impl DedicatedWorkerGlobalScope { let serialized_url = url.serialize(); let parent_sender_for_reporter = parent_sender.clone(); let global = DedicatedWorkerGlobalScope::new( - url, id, mem_profiler_chan.clone(), devtools_chan, runtime.clone(), resource_task, - constellation_chan, parent_sender, own_sender, receiver); + url, id, mem_profiler_chan.clone(), devtools_chan, runtime.clone(), + resource_task, constellation_chan, parent_sender, own_sender, receiver); // FIXME(njn): workers currently don't have a unique ID suitable for using in reporter // registration (#6631), so we instead use a random number and cross our fingers. let reporter_name = format!("worker-reporter-{}", random::()); diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 9df842dddfc..dd7dc90e0fe 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -83,6 +83,7 @@ use layout_interface::{ReflowGoal, ReflowQueryType}; use euclid::point::Point2D; use html5ever::tree_builder::{QuirksMode, NoQuirks, LimitedQuirks, Quirks}; +use ipc_channel::ipc; use layout_interface::{LayoutChan, Msg}; use string_cache::{Atom, QualName}; use url::Url; @@ -283,7 +284,7 @@ pub trait DocumentHelpers<'a> { /// https://w3c.github.io/animation-timing/#dfn-invoke-callbacks-algorithm fn invoke_animation_callbacks(self); fn prepare_async_load(self, load: LoadType) -> PendingAsyncLoad; - fn load_async(self, load: LoadType, listener: Box); + fn load_async(self, load: LoadType, listener: AsyncResponseTarget); fn load_sync(self, load: LoadType) -> Result<(Metadata, Vec), String>; fn finish_load(self, load: LoadType); fn set_current_parser(self, script: Option<&ServoHTMLParser>); @@ -968,7 +969,7 @@ impl<'a> DocumentHelpers<'a> for &'a Document { loader.prepare_async_load(load) } - fn load_async(self, load: LoadType, listener: Box) { + fn load_async(self, load: LoadType, listener: AsyncResponseTarget) { let mut loader = self.loader.borrow_mut(); loader.load_async(load, listener) } @@ -1720,7 +1721,7 @@ impl<'a> DocumentMethods for &'a Document { return Err(Security); } let window = self.window.root(); - let (tx, rx) = channel(); + let (tx, rx) = ipc::channel().unwrap(); let _ = window.r().resource_task().send(GetCookiesForUrl(url, tx, NonHTTP)); let cookies = rx.recv().unwrap(); Ok(cookies.unwrap_or("".to_owned())) diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 3329e0f0af9..b4c8a5e4946 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -40,7 +40,9 @@ use js::jsval::UndefinedValue; use encoding::all::UTF_8; use encoding::label::encoding_from_whatwg_label; use encoding::types::{Encoding, EncodingRef, DecoderTrap}; -use net_traits::{Metadata, AsyncResponseListener}; +use ipc_channel::ipc; +use ipc_channel::router::ROUTER; +use net_traits::{Metadata, AsyncResponseListener, AsyncResponseTarget}; use util::str::{DOMString, HTML_SPACE_CHARACTERS, StaticStringVec}; use html5ever::tree_builder::NextParserState; use std::cell::{RefCell, Cell}; @@ -330,12 +332,19 @@ impl<'a> HTMLScriptElementHelpers for &'a HTMLScriptElement { url: url.clone(), })); + let (action_sender, action_receiver) = ipc::channel().unwrap(); let listener = box NetworkListener { context: context, script_chan: script_chan, }; + let response_target = AsyncResponseTarget { + sender: action_sender, + }; + ROUTER.add_route(action_receiver.to_opaque(), box move |message| { + listener.notify(message.to().unwrap()); + }); - doc.r().load_async(LoadType::Script(url), listener); + doc.r().load_async(LoadType::Script(url), response_target); if self.parser_inserted.get() { doc.r().get_current_parser().unwrap().r().suspend(); diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index d4f2a36eabf..d7a9e9f243a 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -74,8 +74,9 @@ use std::default::Default; use std::ffi::CString; use std::mem as std_mem; use std::rc::Rc; -use std::sync::mpsc::{channel, Receiver}; +use std::sync::Arc; use std::sync::mpsc::TryRecvError::{Empty, Disconnected}; +use std::sync::mpsc::{channel, Receiver}; use time; /// Current state of the window object @@ -173,7 +174,7 @@ pub struct Window { window_size: Cell>, /// Associated resource task for use by DOM objects like XMLHttpRequest - resource_task: ResourceTask, + resource_task: Arc, /// A handle for communicating messages to the storage task. storage_task: StorageTask, @@ -883,7 +884,7 @@ impl<'a> WindowHelpers for &'a Window { } fn resource_task(self) -> ResourceTask { - self.resource_task.clone() + (*self.resource_task).clone() } fn mem_profiler_chan(self) -> mem::ProfilerChan { @@ -1035,7 +1036,7 @@ impl Window { control_chan: ScriptControlChan, compositor: ScriptListener, image_cache_task: ImageCacheTask, - resource_task: ResourceTask, + resource_task: Arc, storage_task: StorageTask, mem_profiler_chan: mem::ProfilerChan, devtools_chan: Option>, diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 9ec68cb0fd2..980683114a2 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -46,12 +46,14 @@ use js::jsval::{JSVal, NullValue, UndefinedValue}; use net_traits::ControlMsg::Load; use net_traits::{ResourceTask, ResourceCORSData, LoadData, LoadConsumer}; -use net_traits::{AsyncResponseListener, Metadata}; +use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata}; use cors::{allow_cross_origin_request, CORSRequest, RequestMode, AsyncCORSResponseListener}; use cors::CORSResponse; use util::str::DOMString; use util::task::spawn_named; +use ipc_channel::ipc; +use ipc_channel::router::ROUTER; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::cell::{RefCell, Cell}; @@ -270,11 +272,18 @@ impl XMLHttpRequest { } } + let (action_sender, action_receiver) = ipc::channel().unwrap(); let listener = box NetworkListener { context: context, script_chan: script_chan, }; - resource_task.send(Load(load_data, LoadConsumer::Listener(listener))).unwrap(); + let response_target = AsyncResponseTarget { + sender: action_sender, + }; + ROUTER.add_route(action_receiver.to_opaque(), box move |message| { + listener.notify(message.to().unwrap()); + }); + resource_task.send(Load(load_data, LoadConsumer::Listener(response_target))).unwrap(); } } @@ -558,8 +567,11 @@ impl<'a> XMLHttpRequestMethods for &'a XMLHttpRequest { }; let mut combined_headers = load_data.headers.clone(); combined_headers.extend(load_data.preserved_headers.iter()); - let cors_request = CORSRequest::maybe_new(referer_url.clone(), load_data.url.clone(), mode, - load_data.method.clone(), combined_headers); + let cors_request = CORSRequest::maybe_new(referer_url.clone(), + load_data.url.clone(), + mode, + load_data.method.clone(), + combined_headers); match cors_request { Ok(None) => { let mut buf = String::new(); @@ -781,7 +793,8 @@ impl<'a> PrivateXMLHttpRequestHelpers for &'a XMLHttpRequest { }; // XXXManishearth Clear cache entries in case of a network error self.process_partial_response(XHRProgress::HeadersReceived(gen_id, - metadata.headers, metadata.status)); + metadata.headers, + metadata.status)); Ok(()) } diff --git a/components/script/network_listener.rs b/components/script/network_listener.rs index 5f400eb76b3..7ede86e0742 100644 --- a/components/script/network_listener.rs +++ b/components/script/network_listener.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use script_task::{ScriptChan, ScriptMsg, Runnable}; -use net_traits::{AsyncResponseTarget, AsyncResponseListener, ResponseAction}; +use net_traits::{AsyncResponseListener, ResponseAction}; use std::sync::{Arc, Mutex}; /// An off-thread sink for async network event runnables. All such events are forwarded to @@ -13,12 +13,14 @@ pub struct NetworkListener, } -impl AsyncResponseTarget for NetworkListener { - fn invoke_with_listener(&self, action: ResponseAction) { - self.script_chan.send(ScriptMsg::RunnableMsg(box ListenerRunnable { +impl NetworkListener { + pub fn notify(&self, action: ResponseAction) { + if let Err(err) = self.script_chan.send(ScriptMsg::RunnableMsg(box ListenerRunnable { context: self.context.clone(), action: action, - })).unwrap(); + })) { + warn!("failed to deliver network data: {:?}", err); + } } } diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 7deed84430d..bf23bca2db6 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -67,8 +67,8 @@ use msg::constellation_msg::{LoadData, PipelineId, SubpageId, MozBrowserEvent, W use msg::constellation_msg::{Failure, WindowSizeData, PipelineExitType}; use msg::constellation_msg::Msg as ConstellationMsg; use msg::webdriver_msg::WebDriverScriptCommand; -use net_traits::{ResourceTask, LoadConsumer, ControlMsg, Metadata}; use net_traits::LoadData as NetLoadData; +use net_traits::{AsyncResponseTarget, ResourceTask, LoadConsumer, ControlMsg, Metadata}; use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask, ImageCacheResult}; use net_traits::storage_task::StorageTask; use profile_traits::mem::{self, Report, Reporter, ReporterRequest, ReportKind, ReportsChan}; @@ -287,8 +287,9 @@ pub struct ScriptTask { incomplete_loads: DOMRefCell>, /// A handle to the image cache task. image_cache_task: ImageCacheTask, - /// A handle to the resource task. - resource_task: ResourceTask, + /// A handle to the resource task. This is an `Arc` to avoid running out of file descriptors if + /// there are many iframes. + resource_task: Arc, /// A handle to the storage task. storage_task: StorageTask, @@ -418,7 +419,7 @@ impl ScriptTaskFactory for ScriptTask { control_chan, control_port, constellation_chan, - resource_task, + Arc::new(resource_task), storage_task, image_cache_task, mem_profiler_chan.clone(), @@ -504,7 +505,7 @@ impl ScriptTask { control_chan: ScriptControlChan, control_port: Receiver, constellation_chan: ConstellationChan, - resource_task: ResourceTask, + resource_task: Arc, storage_task: StorageTask, image_cache_task: ImageCacheTask, mem_profiler_chan: mem::ProfilerChan, @@ -1415,7 +1416,9 @@ impl ScriptTask { }); let content_type = match metadata.content_type { - Some(ContentType(Mime(TopLevel::Text, SubLevel::Plain, _))) => Some("text/plain".to_owned()), + Some(ContentType(Mime(TopLevel::Text, SubLevel::Plain, _))) => { + Some("text/plain".to_owned()) + } _ => None }; @@ -1680,10 +1683,17 @@ impl ScriptTask { let context = Arc::new(Mutex::new(ParserContext::new(id, subpage, script_chan.clone(), load_data.url.clone()))); + let (action_sender, action_receiver) = ipc::channel().unwrap(); let listener = box NetworkListener { context: context, script_chan: script_chan.clone(), }; + ROUTER.add_route(action_receiver.to_opaque(), box move |message| { + listener.notify(message.to().unwrap()); + }); + let response_target = AsyncResponseTarget { + sender: action_sender, + }; if load_data.url.scheme == "javascript" { load_data.url = Url::parse("about:blank").unwrap(); @@ -1697,7 +1707,7 @@ impl ScriptTask { data: load_data.data, cors: None, pipeline_id: Some(id), - }, LoadConsumer::Listener(listener))).unwrap(); + }, LoadConsumer::Listener(response_target))).unwrap(); self.incomplete_loads.borrow_mut().push(incomplete); } diff --git a/components/script_traits/Cargo.toml b/components/script_traits/Cargo.toml index d902192f700..ddd29bbb524 100644 --- a/components/script_traits/Cargo.toml +++ b/components/script_traits/Cargo.toml @@ -25,8 +25,11 @@ path = "../devtools_traits" [dependencies.ipc-channel] git = "https://github.com/pcwalton/ipc-channel" +[dependencies.url] +version = "0.2" +features = [ "serde_serialization" ] + [dependencies] -url = "0.2.36" libc = "0.1" euclid = "0.1" serde = "0.4" diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 8415a423b61..7c969ece482 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -910,6 +910,7 @@ version = "0.0.1" dependencies = [ "cookie 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "net 0.0.1", "net_traits 0.0.1", "time 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml index b96b734147e..00a30da7962 100644 --- a/components/servo/Cargo.toml +++ b/components/servo/Cargo.toml @@ -100,9 +100,12 @@ optional = true path = "../../support/android-rs-glue/glue" optional = true +[dependencies.url] +version = "0.2" +features = [ "serde_serialization" ] + [dependencies] env_logger = "0.3" -url = "0.2.36" time = "0.1.12" bitflags = "0.3" libc = "0.1" diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml index 79259bfb392..110deb31879 100644 --- a/components/style/Cargo.toml +++ b/components/style/Cargo.toml @@ -23,13 +23,16 @@ features = ["unstable"] version = "0.3" features = [ "serde-serialization" ] +[dependencies.url] +version = "0.2" +features = [ "serde_serialization" ] + [dependencies] log = "0.3" encoding = "0.2" fnv = "1.0" rustc-serialize = "0.3" matches = "0.1" -url = "0.2.36" bitflags = "0.3" num = "0.1.24" lazy_static = "0.1.10" diff --git a/components/util/Cargo.toml b/components/util/Cargo.toml index 6558792b21b..4d9027653f9 100644 --- a/components/util/Cargo.toml +++ b/components/util/Cargo.toml @@ -28,6 +28,10 @@ features = [ "serde-serialization" ] [dependencies.ipc-channel] git = "https://github.com/pcwalton/ipc-channel" +[dependencies.url] +version = "0.2" +features = [ "serde_serialization" ] + [dependencies] log = "0.3" bitflags = "0.3" @@ -37,7 +41,6 @@ rustc-serialize = "0.3" smallvec = "0.1" num_cpus = "0.2.2" num = "0.1.24" -url = "0.2.36" euclid = "0.1" serde = "0.4" serde_macros = "0.4" diff --git a/components/webdriver_server/Cargo.toml b/components/webdriver_server/Cargo.toml index 7fb28951fb8..61a7f2ba361 100644 --- a/components/webdriver_server/Cargo.toml +++ b/components/webdriver_server/Cargo.toml @@ -23,8 +23,11 @@ features = [ "serde-serialization" ] [dependencies.ipc-channel] git = "https://github.com/pcwalton/ipc-channel" +[dependencies.url] +version = "0.2" +features = [ "serde_serialization" ] + [dependencies] log = "0.3" rustc-serialize = "0.3.4" -url = "0.2.36" uuid = "0.1" diff --git a/tests/unit/net/Cargo.toml b/tests/unit/net/Cargo.toml index 5e9608356c7..62c72b975bc 100644 --- a/tests/unit/net/Cargo.toml +++ b/tests/unit/net/Cargo.toml @@ -17,6 +17,9 @@ path = "../../../components/net_traits" [dependencies.util] path = "../../../components/util" +[dependencies.ipc-channel] +git = "https://github.com/pcwalton/ipc-channel" + [dependencies] cookie = "0.1" hyper = "0.6" diff --git a/tests/unit/net/data_loader.rs b/tests/unit/net/data_loader.rs index 362fd4c5193..702083798a5 100644 --- a/tests/unit/net/data_loader.rs +++ b/tests/unit/net/data_loader.rs @@ -4,6 +4,7 @@ extern crate hyper; +use ipc_channel::ipc; use net_traits::LoadConsumer::Channel; use net_traits::LoadData; use net_traits::ProgressMsg::{Payload, Done}; @@ -19,7 +20,7 @@ fn assert_parse(url: &'static str, use url::Url; use net::data_loader::load; - let (start_chan, start_port) = channel(); + let (start_chan, start_port) = ipc::channel().unwrap(); load(LoadData::new(Url::parse(url).unwrap(), None), Channel(start_chan)); let response = start_port.recv().unwrap(); diff --git a/tests/unit/net/hsts.rs b/tests/unit/net/hsts.rs index 56deee0927f..7ac11d4dbc3 100644 --- a/tests/unit/net/hsts.rs +++ b/tests/unit/net/hsts.rs @@ -7,6 +7,7 @@ use net::hsts::HSTSEntry; use net_traits::IncludeSubdomains; use net::hsts::{secure_url, preload_hsts_domains}; use net::resource_task::ResourceManager; +use ipc_channel::ipc; use std::sync::mpsc::channel; use url::Url; use time; @@ -17,7 +18,7 @@ fn test_add_hsts_entry_to_resource_manager_adds_an_hsts_entry() { entries: Vec::new() }; - let (tx, _) = channel(); + let (tx, _) = ipc::channel().unwrap(); let mut manager = ResourceManager::new(None, tx, list, None); let entry = HSTSEntry::new( diff --git a/tests/unit/net/lib.rs b/tests/unit/net/lib.rs index d9d0f05a79f..3f737fc1783 100644 --- a/tests/unit/net/lib.rs +++ b/tests/unit/net/lib.rs @@ -4,6 +4,7 @@ #![cfg_attr(test, feature(box_raw))] +extern crate ipc_channel; extern crate net; extern crate net_traits; extern crate url; diff --git a/tests/unit/net/resource_task.rs b/tests/unit/net/resource_task.rs index 989558c2f21..05b719373ea 100644 --- a/tests/unit/net/resource_task.rs +++ b/tests/unit/net/resource_task.rs @@ -2,9 +2,8 @@ * 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::resource_task::new_resource_task; -use net::resource_task::parse_hostsfile; -use net::resource_task::replace_hosts; +use ipc_channel::ipc; +use net::resource_task::{new_resource_task, parse_hostsfile, replace_hosts}; use net_traits::{ControlMsg, LoadData, LoadConsumer}; use net_traits::ProgressMsg; use std::borrow::ToOwned; @@ -21,7 +20,7 @@ fn test_exit() { #[test] fn test_bad_scheme() { let resource_task = new_resource_task(None, None); - let (start_chan, start) = channel(); + let (start_chan, start) = ipc::channel().unwrap(); let url = Url::parse("bogus://whatever").unwrap(); resource_task.send(ControlMsg::Load(LoadData::new(url, None), LoadConsumer::Channel(start_chan))).unwrap(); let response = start.recv().unwrap(); @@ -170,7 +169,7 @@ fn test_replace_hosts() { //Start the resource task and make a request to our TCP server let resource_task = new_resource_task(None, None); - let (start_chan, _) = channel(); + let (start_chan, _start_port) = ipc::channel().unwrap(); let url = Url::parse(&format!("http://foo.bar.com:{}", port)).unwrap(); let msg = ControlMsg::Load(replace_hosts(LoadData::new(url, None), host_table), LoadConsumer::Channel(start_chan));