Urlmageddon: Use refcounted urls more often.

This commit is contained in:
Emilio Cobos Álvarez 2016-11-16 11:57:39 +01:00
parent f14e7339b5
commit 913c874cb5
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
161 changed files with 1044 additions and 718 deletions

View file

@ -11,6 +11,7 @@ use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheCommand, ImageCac
use net_traits::image_cache_thread::{ImageCacheResult, ImageOrMetadataAvailable, ImageResponse, UsePlaceholder};
use net_traits::image_cache_thread::ImageResponder;
use net_traits::request::{Destination, RequestInit, Type as RequestType};
use servo_url::ServoUrl;
use std::borrow::ToOwned;
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
@ -20,7 +21,6 @@ use std::mem;
use std::sync::Arc;
use std::sync::mpsc::{Receiver, Sender, channel};
use threadpool::ThreadPool;
use url::Url;
use util::resource_files::resources_dir_path;
use util::thread::spawn_named;
use webrender_traits;
@ -49,7 +49,7 @@ struct PendingLoad {
// The url being loaded. Do not forget that this may be several Mb
// if we are loading a data: url.
url: Arc<Url>
url: ServoUrl,
}
enum LoadResult {
@ -59,7 +59,7 @@ enum LoadResult {
}
impl PendingLoad {
fn new(url: Arc<Url>) -> PendingLoad {
fn new(url: ServoUrl) -> PendingLoad {
PendingLoad {
bytes: vec!(),
metadata: None,
@ -83,7 +83,7 @@ struct AllPendingLoads {
// Get a load key from its url. Used ony when starting and
// finishing a load or when adding a new listener.
url_to_load_key: HashMap<Arc<Url>, LoadKey>,
url_to_load_key: HashMap<ServoUrl, LoadKey>,
// A counter used to generate instances of LoadKey
keygen: LoadKeyGenerator,
@ -118,7 +118,7 @@ impl AllPendingLoads {
}
// get a PendingLoad from its url. When possible, prefer `get_by_key_mut`.
fn get_by_url(&self, url: &Url) -> Option<&PendingLoad> {
fn get_by_url(&self, url: &ServoUrl) -> Option<&PendingLoad> {
self.url_to_load_key.get(url).
and_then(|load_key|
self.loads.get(load_key)
@ -133,7 +133,7 @@ impl AllPendingLoads {
})
}
fn get_cached(&mut self, url: Arc<Url>) -> (CacheResult, LoadKey, &mut PendingLoad) {
fn get_cached(&mut self, url: ServoUrl) -> (CacheResult, LoadKey, &mut PendingLoad) {
match self.url_to_load_key.entry(url.clone()) {
Occupied(url_entry) => {
let load_key = url_entry.get();
@ -255,7 +255,7 @@ struct ImageCache {
pending_loads: AllPendingLoads,
// Images that have finished loading (successful or not)
completed_loads: HashMap<Arc<Url>, CompletedLoad>,
completed_loads: HashMap<ServoUrl, CompletedLoad>,
// The placeholder image used when an image fails to load
placeholder_image: Option<Arc<Image>>,
@ -498,7 +498,7 @@ impl ImageCache {
};
let completed_load = CompletedLoad::new(image_response.clone());
self.completed_loads.insert(pending_load.url, completed_load);
self.completed_loads.insert(pending_load.url.into(), completed_load);
for listener in pending_load.listeners {
listener.notify(image_response.clone());
@ -511,23 +511,21 @@ impl ImageCache {
// that image metadata is available, possibly before the image has finished
// loading.
fn request_image(&mut self,
url: Url,
url: ServoUrl,
result_chan: ImageCacheChan,
responder: Option<ImageResponder>,
send_metadata_msg: bool) {
let image_listener = ImageListener::new(result_chan, responder, send_metadata_msg);
// Let's avoid copying url everywhere.
let ref_url = Arc::new(url);
// Check if already completed
match self.completed_loads.get(&ref_url) {
match self.completed_loads.get(&url) {
Some(completed_load) => {
// It's already completed, return a notify straight away
image_listener.notify(completed_load.image_response.clone());
}
None => {
// Check if the load is already pending
let (cache_result, load_key, mut pending_load) = self.pending_loads.get_cached(ref_url.clone());
let (cache_result, load_key, mut pending_load) = self.pending_loads.get_cached(url.clone());
pending_load.add_listener(image_listener);
match cache_result {
CacheResult::Miss => {
@ -535,11 +533,13 @@ impl ImageCache {
// the resource thread.
// https://html.spec.whatwg.org/multipage/#update-the-image-data
// step 12.
//
// TODO(emilio): ServoUrl in more places please!
let request = RequestInit {
url: (*ref_url).clone(),
url: url.clone(),
type_: RequestType::Image,
destination: Destination::Image,
origin: (*ref_url).clone(),
origin: url.clone(),
.. RequestInit::default()
};
@ -578,9 +578,9 @@ impl ImageCache {
}
fn get_image_if_available(&mut self,
url: Url,
placeholder: UsePlaceholder, )
-> Result<Arc<Image>, ImageState> {
url: ServoUrl,
placeholder: UsePlaceholder, )
-> Result<Arc<Image>, ImageState> {
let img_or_metadata = self.get_image_or_meta_if_available(url, placeholder);
match img_or_metadata {
Ok(ImageOrMetadataAvailable::ImageAvailable(image)) => Ok(image),
@ -590,7 +590,7 @@ impl ImageCache {
}
fn get_image_or_meta_if_available(&mut self,
url: Url,
url: ServoUrl,
placeholder: UsePlaceholder)
-> Result<ImageOrMetadataAvailable, ImageState> {
match self.completed_loads.get(&url) {
@ -624,9 +624,9 @@ impl ImageCache {
}
fn store_decode_image(&mut self,
ref_url: Url,
ref_url: ServoUrl,
loaded_bytes: Vec<u8>) {
let (cache_result, load_key, _) = self.pending_loads.get_cached(Arc::new(ref_url));
let (cache_result, load_key, _) = self.pending_loads.get_cached(ref_url.clone());
assert!(cache_result == CacheResult::Miss);
let action = ResponseAction::DataAvailable(loaded_bytes);
let _ = self.progress_sender.send(ResourceLoadInfo {