Implement trait-based ResourceThreads and clean up related naming issues

Changes include:

- Introduce an IpcSend trait to abstract over a collection of IpcSenders
- Implement ResourceThreads collection to abstract the resource-related
  sub threads across the component
- Rename original ResourceThread and ControlMsg into an unifed CoreResource__
  to accommodate above changes and avoid confusions
This commit is contained in:
Zhen Zhang 2016-05-18 00:07:42 +08:00
parent 051a749e0d
commit a51db4cfa8
22 changed files with 213 additions and 179 deletions

View file

@ -8,7 +8,6 @@
#![feature(plugin)]
#![feature(slice_patterns)]
#![feature(step_by)]
#![feature(custom_attribute)]
#![plugin(heapsize_plugin, serde_macros)]
#![deny(unsafe_code)]
@ -29,14 +28,17 @@ extern crate util;
extern crate uuid;
extern crate websocket;
use heapsize::HeapSizeOf;
use hyper::header::{ContentType, Headers};
use hyper::http::RawStatus;
use hyper::method::Method;
use hyper::mime::{Attr, Mime};
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
use std::io::Error as IOError;
use std::sync::mpsc::Sender;
use std::thread;
use storage_thread::{StorageThread, StorageThreadMsg};
use url::Url;
use websocket::header;
@ -180,7 +182,59 @@ pub enum LoadConsumer {
}
/// Handle to a resource thread
pub type ResourceThread = IpcSender<ControlMsg>;
pub type CoreResourceThread = IpcSender<CoreResourceMsg>;
pub type IpcSendResult = Result<(), IOError>;
pub trait IpcSend<T> where T: serde::Serialize + serde::Deserialize {
fn send(&self, T) -> IpcSendResult;
fn sender(&self) -> IpcSender<T>;
}
// FIXME: Originally we will construct an Arc<ResourceThread> from ResourceThread
// in script_thread to avoid some performance pitfall. Now we decide to deal with
// the "Arc" hack implicitly in future.
// See discussion: http://logs.glob.uno/?c=mozilla%23servo&s=16+May+2016&e=16+May+2016#c430412
// See also: https://github.com/servo/servo/blob/735480/components/script/script_thread.rs#L313
#[derive(Clone, Serialize, Deserialize)]
pub struct ResourceThreads {
core_thread: CoreResourceThread,
storage_thread: StorageThread,
}
impl ResourceThreads {
pub fn new(c: CoreResourceThread, s: StorageThread) -> ResourceThreads {
ResourceThreads {
core_thread: c,
storage_thread: s,
}
}
}
impl IpcSend<CoreResourceMsg> for ResourceThreads {
fn send(&self, msg: CoreResourceMsg) -> IpcSendResult {
self.core_thread.send(msg)
}
fn sender(&self) -> IpcSender<CoreResourceMsg> {
self.core_thread.clone()
}
}
impl IpcSend<StorageThreadMsg> for ResourceThreads {
fn send(&self, msg: StorageThreadMsg) -> IpcSendResult {
self.storage_thread.send(msg)
}
fn sender(&self) -> IpcSender<StorageThreadMsg> {
self.storage_thread.clone()
}
}
// Ignore the sub-fields
impl HeapSizeOf for ResourceThreads {
fn heap_size_of_children(&self) -> usize { 0 }
}
#[derive(PartialEq, Copy, Clone, Deserialize, Serialize)]
pub enum IncludeSubdomains {
@ -222,7 +276,7 @@ pub struct WebSocketConnectData {
}
#[derive(Deserialize, Serialize)]
pub enum ControlMsg {
pub enum CoreResourceMsg {
/// Request the data associated with a particular URL
Load(LoadData, LoadConsumer, Option<IpcSender<ResourceId>>),
/// Try to make a websocket connection to a URL.
@ -243,7 +297,7 @@ pub enum ControlMsg {
/// the resource thread to make a new request. The `load` method *must* be called before
/// destruction or the thread will panic.
pub struct PendingAsyncLoad {
resource_thread: ResourceThread,
core_resource_thread: CoreResourceThread,
url: Url,
pipeline: Option<PipelineId>,
guard: PendingLoadGuard,
@ -272,14 +326,14 @@ impl Drop for PendingLoadGuard {
impl PendingAsyncLoad {
pub fn new(context: LoadContext,
resource_thread: ResourceThread,
core_resource_thread: CoreResourceThread,
url: Url,
pipeline: Option<PipelineId>,
referrer_policy: Option<ReferrerPolicy>,
referrer_url: Option<Url>)
-> PendingAsyncLoad {
PendingAsyncLoad {
resource_thread: resource_thread,
core_resource_thread: core_resource_thread,
url: url,
pipeline: pipeline,
guard: PendingLoadGuard { loaded: false, },
@ -294,7 +348,7 @@ impl PendingAsyncLoad {
self.guard.neuter();
let load_data = LoadData::new(self.context, self.url, self.pipeline, self.referrer_policy, self.referrer_url);
let consumer = LoadConsumer::Listener(listener);
self.resource_thread.send(ControlMsg::Load(load_data, consumer, None)).unwrap();
self.core_resource_thread.send(CoreResourceMsg::Load(load_data, consumer, None)).unwrap();
}
}
@ -404,13 +458,13 @@ pub enum ProgressMsg {
/// Convenience function for synchronously loading a whole resource.
pub fn load_whole_resource(context: LoadContext,
resource_thread: &ResourceThread,
core_resource_thread: &CoreResourceThread,
url: Url,
pipeline_id: Option<PipelineId>)
-> Result<(Metadata, Vec<u8>), NetworkError> {
let (start_chan, start_port) = ipc::channel().unwrap();
resource_thread.send(ControlMsg::Load(LoadData::new(context, url, pipeline_id, None, None),
LoadConsumer::Channel(start_chan), None)).unwrap();
core_resource_thread.send(CoreResourceMsg::Load(LoadData::new(context, url, pipeline_id, None, None),
LoadConsumer::Channel(start_chan), None)).unwrap();
let response = start_port.recv().unwrap();
let mut buf = vec!();