mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
script: Make the resource task communication use IPC channels.
This commit is contained in:
parent
44d13f7fd4
commit
2aa5174246
35 changed files with 234 additions and 458 deletions
|
@ -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"] }
|
||||
|
|
|
@ -11,13 +11,11 @@
|
|||
|
||||
use network_listener::{NetworkListener, PreInvoke};
|
||||
use script_task::ScriptChan;
|
||||
use net_traits::{AsyncResponseTarget, AsyncResponseListener, ResponseAction, Metadata};
|
||||
use net_traits::{SerializableStringResult};
|
||||
use net_traits::{AsyncResponseListener, ResponseAction, Metadata};
|
||||
|
||||
use std::ascii::AsciiExt;
|
||||
use std::borrow::ToOwned;
|
||||
use std::cell::RefCell;
|
||||
use std::sync::mpsc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use time;
|
||||
use time::{now, Timespec};
|
||||
|
@ -133,14 +131,9 @@ impl CORSRequest {
|
|||
listener: listener,
|
||||
response: RefCell::new(None),
|
||||
};
|
||||
let (action_sender, action_receiver) = mpsc::channel();
|
||||
let listener = NetworkListener {
|
||||
context: Arc::new(Mutex::new(context)),
|
||||
script_chan: script_chan,
|
||||
receiver: action_receiver,
|
||||
};
|
||||
let response_target = AsyncResponseTarget {
|
||||
sender: action_sender,
|
||||
};
|
||||
|
||||
// TODO: this exists only to make preflight check non-blocking
|
||||
|
@ -151,8 +144,7 @@ impl CORSRequest {
|
|||
let mut context = listener.context.lock();
|
||||
let context = context.as_mut().unwrap();
|
||||
*context.response.borrow_mut() = Some(response);
|
||||
response_target.invoke_with_listener(ResponseAction::ResponseComplete(
|
||||
SerializableStringResult(Ok(()))));
|
||||
listener.notify(ResponseAction::ResponseComplete(Ok(())));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -356,9 +357,10 @@ impl JSTraceable for Box<LayoutRPC+'static> {
|
|||
}
|
||||
}
|
||||
|
||||
impl JSTraceable for () {
|
||||
impl<T> JSTraceable for IpcReceiver<T> where T: Deserialize + Serialize {
|
||||
#[inline]
|
||||
fn trace(&self, _trc: *mut JSTracer) {
|
||||
fn trace(&self, _: *mut JSTracer) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -181,7 +181,7 @@ impl DedicatedWorkerGlobalScope {
|
|||
let serialized_url = url.serialize();
|
||||
let parent_sender_for_reporter = parent_sender.clone();
|
||||
let global = DedicatedWorkerGlobalScope::new(
|
||||
url.0, id, mem_profiler_chan.clone(), devtools_chan, runtime.clone(),
|
||||
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.
|
||||
|
|
|
@ -74,7 +74,7 @@ use msg::constellation_msg::{ConstellationChan, FocusType, Key, KeyState, KeyMod
|
|||
use msg::constellation_msg::{SUPER, ALT, SHIFT, CONTROL};
|
||||
use net_traits::CookieSource::NonHTTP;
|
||||
use net_traits::ControlMsg::{SetCookiesForUrl, GetCookiesForUrl};
|
||||
use net_traits::{Metadata, PendingAsyncLoad, AsyncResponseTarget, SerializableUrl};
|
||||
use net_traits::{Metadata, PendingAsyncLoad, AsyncResponseTarget};
|
||||
use script_task::Runnable;
|
||||
use script_traits::{MouseButton, UntrustedNodeAddress};
|
||||
use util::opts;
|
||||
|
@ -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;
|
||||
|
@ -1720,10 +1721,8 @@ impl<'a> DocumentMethods for &'a Document {
|
|||
return Err(Security);
|
||||
}
|
||||
let window = self.window.root();
|
||||
let (tx, rx) = channel();
|
||||
let _ = window.r().resource_task().send(GetCookiesForUrl(SerializableUrl(url),
|
||||
tx,
|
||||
NonHTTP));
|
||||
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()))
|
||||
}
|
||||
|
@ -1736,9 +1735,7 @@ impl<'a> DocumentMethods for &'a Document {
|
|||
return Err(Security);
|
||||
}
|
||||
let window = self.window.root();
|
||||
let _ = window.r().resource_task().send(SetCookiesForUrl(SerializableUrl(url),
|
||||
cookie,
|
||||
NonHTTP));
|
||||
let _ = window.r().resource_task().send(SetCookiesForUrl(url, cookie, NonHTTP));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -40,14 +40,14 @@ use js::jsval::UndefinedValue;
|
|||
use encoding::all::UTF_8;
|
||||
use encoding::label::encoding_from_whatwg_label;
|
||||
use encoding::types::{Encoding, EncodingRef, DecoderTrap};
|
||||
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};
|
||||
use std::mem;
|
||||
use std::sync::mpsc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use string_cache::Atom;
|
||||
use url::{Url, UrlParser};
|
||||
|
||||
|
@ -332,16 +332,17 @@ impl<'a> HTMLScriptElementHelpers for &'a HTMLScriptElement {
|
|||
url: url.clone(),
|
||||
}));
|
||||
|
||||
let (action_sender, action_receiver) = mpsc::channel();
|
||||
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
||||
let listener = box NetworkListener {
|
||||
context: context,
|
||||
script_chan: script_chan,
|
||||
receiver: action_receiver,
|
||||
};
|
||||
let response_target = AsyncResponseTarget {
|
||||
sender: action_sender,
|
||||
};
|
||||
thread::spawn(move || listener.run());
|
||||
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
|
||||
listener.notify(message.to().unwrap());
|
||||
});
|
||||
|
||||
doc.r().load_async(LoadType::Script(url), response_target);
|
||||
|
||||
|
@ -400,7 +401,7 @@ impl<'a> HTMLScriptElementHelpers for &'a HTMLScriptElement {
|
|||
// encoding as the fallback encoding.
|
||||
|
||||
(UTF_8.decode(&*bytes, DecoderTrap::Replace).unwrap(), true,
|
||||
metadata.final_url.0)
|
||||
metadata.final_url)
|
||||
},
|
||||
|
||||
// Step 2.b.1.c.
|
||||
|
|
|
@ -84,7 +84,7 @@ impl ParserContext {
|
|||
|
||||
impl AsyncResponseListener for ParserContext {
|
||||
fn headers_available(&self, metadata: Metadata) {
|
||||
let content_type = metadata.content_type.clone().map(|content_type| content_type.0);
|
||||
let content_type = metadata.content_type.clone();
|
||||
|
||||
let parser = ScriptTask::page_fetch_complete(self.id.clone(), self.subpage.clone(),
|
||||
metadata);
|
||||
|
|
|
@ -46,20 +46,21 @@ use js::jsval::{JSVal, NullValue, UndefinedValue};
|
|||
|
||||
use net_traits::ControlMsg::Load;
|
||||
use net_traits::{ResourceTask, ResourceCORSData, LoadData, LoadConsumer};
|
||||
use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata, SerializableHeaders};
|
||||
use net_traits::{SerializableMethod, SerializableUrl};
|
||||
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};
|
||||
use std::default::Default;
|
||||
use std::sync::{Mutex, Arc};
|
||||
use std::sync::mpsc::{channel, Sender, TryRecvError};
|
||||
use std::thread::{self, sleep_ms};
|
||||
use std::thread::sleep_ms;
|
||||
use time;
|
||||
use url::{Url, UrlParser};
|
||||
|
||||
|
@ -217,7 +218,7 @@ impl XMLHttpRequest {
|
|||
let mut load_data = self.load_data.borrow_mut().take().unwrap();
|
||||
load_data.cors = Some(ResourceCORSData {
|
||||
preflight: self.req.preflight_flag,
|
||||
origin: SerializableUrl(self.req.origin.clone())
|
||||
origin: self.req.origin.clone()
|
||||
});
|
||||
|
||||
XMLHttpRequest::initiate_async_xhr(self.xhr.clone(), self.script_chan.clone(),
|
||||
|
@ -271,16 +272,17 @@ impl XMLHttpRequest {
|
|||
}
|
||||
}
|
||||
|
||||
let (action_sender, action_receiver) = channel();
|
||||
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
||||
let listener = box NetworkListener {
|
||||
context: context,
|
||||
script_chan: script_chan,
|
||||
receiver: action_receiver,
|
||||
};
|
||||
let response_target = AsyncResponseTarget {
|
||||
sender: action_sender,
|
||||
};
|
||||
thread::spawn(move || listener.run());
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -546,15 +548,14 @@ impl<'a> XMLHttpRequestMethods for &'a XMLHttpRequest {
|
|||
None => ()
|
||||
}
|
||||
|
||||
load_data.preserved_headers =
|
||||
SerializableHeaders((*self.request_headers.borrow()).clone());
|
||||
load_data.preserved_headers = (*self.request_headers.borrow()).clone();
|
||||
|
||||
if !load_data.preserved_headers.has::<Accept>() {
|
||||
let mime = Mime(mime::TopLevel::Star, mime::SubLevel::Star, vec![]);
|
||||
load_data.preserved_headers.set(Accept(vec![qitem(mime)]));
|
||||
}
|
||||
|
||||
load_data.method = SerializableMethod((*self.request_method.borrow()).clone());
|
||||
load_data.method = (*self.request_method.borrow()).clone();
|
||||
|
||||
// CORS stuff
|
||||
let global = self.global.root();
|
||||
|
@ -564,12 +565,12 @@ impl<'a> XMLHttpRequestMethods for &'a XMLHttpRequest {
|
|||
} else {
|
||||
RequestMode::CORS
|
||||
};
|
||||
let mut combined_headers = (*load_data.headers).clone();
|
||||
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(),
|
||||
load_data.url.clone(),
|
||||
mode,
|
||||
(*load_data.method).clone(),
|
||||
load_data.method.clone(),
|
||||
combined_headers);
|
||||
match cors_request {
|
||||
Ok(None) => {
|
||||
|
@ -791,10 +792,9 @@ 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.map(|headers| headers.0),
|
||||
metadata.status.map(|status| status.0)));
|
||||
self.process_partial_response(XHRProgress::HeadersReceived(gen_id,
|
||||
metadata.headers,
|
||||
metadata.status));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
use script_task::{ScriptChan, ScriptMsg, Runnable};
|
||||
use net_traits::{AsyncResponseListener, ResponseAction};
|
||||
use std::sync::mpsc::Receiver;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
/// An off-thread sink for async network event runnables. All such events are forwarded to
|
||||
|
@ -12,17 +11,14 @@ use std::sync::{Arc, Mutex};
|
|||
pub struct NetworkListener<T: AsyncResponseListener + PreInvoke + Send + 'static> {
|
||||
pub context: Arc<Mutex<T>>,
|
||||
pub script_chan: Box<ScriptChan+Send>,
|
||||
pub receiver: Receiver<ResponseAction>,
|
||||
}
|
||||
|
||||
impl<T: AsyncResponseListener + PreInvoke + Send + 'static> NetworkListener<T> {
|
||||
pub fn run(&self) {
|
||||
while let Ok(action) = self.receiver.recv() {
|
||||
self.script_chan.send(ScriptMsg::RunnableMsg(box ListenerRunnable {
|
||||
context: self.context.clone(),
|
||||
action: action,
|
||||
})).unwrap();
|
||||
}
|
||||
pub fn notify(&self, action: ResponseAction) {
|
||||
self.script_chan.send(ScriptMsg::RunnableMsg(box ListenerRunnable {
|
||||
context: self.context.clone(),
|
||||
action: action,
|
||||
})).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,8 +69,6 @@ use msg::constellation_msg::Msg as ConstellationMsg;
|
|||
use msg::webdriver_msg::WebDriverScriptCommand;
|
||||
use net_traits::LoadData as NetLoadData;
|
||||
use net_traits::{AsyncResponseTarget, ResourceTask, LoadConsumer, ControlMsg, Metadata};
|
||||
use net_traits::{SerializableContentType, SerializableHeaders, SerializableMethod};
|
||||
use net_traits::{SerializableUrl};
|
||||
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};
|
||||
|
@ -105,7 +103,6 @@ use std::rc::Rc;
|
|||
use std::result::Result;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::mpsc::{channel, Sender, Receiver, Select};
|
||||
use std::thread;
|
||||
use time::Tm;
|
||||
|
||||
use hyper::header::{ContentType, HttpDate};
|
||||
|
@ -1312,7 +1309,7 @@ impl ScriptTask {
|
|||
/// The entry point to document loading. Defines bindings, sets up the window and document
|
||||
/// objects, parses HTML and CSS, and kicks off initial layout.
|
||||
fn load(&self, metadata: Metadata, incomplete: InProgressLoad) -> Root<ServoHTMLParser> {
|
||||
let final_url = (*metadata.final_url).clone();
|
||||
let final_url = metadata.final_url.clone();
|
||||
debug!("ScriptTask: loading {} on page {:?}", incomplete.url.serialize(), incomplete.pipeline_id);
|
||||
|
||||
// We should either be initializing a root page or loading a child page of an
|
||||
|
@ -1418,9 +1415,7 @@ impl ScriptTask {
|
|||
});
|
||||
|
||||
let content_type = match metadata.content_type {
|
||||
Some(SerializableContentType(ContentType(Mime(TopLevel::Text,
|
||||
SubLevel::Plain,
|
||||
_)))) => {
|
||||
Some(ContentType(Mime(TopLevel::Text, SubLevel::Plain, _))) => {
|
||||
Some("text/plain".to_owned())
|
||||
}
|
||||
_ => None
|
||||
|
@ -1687,13 +1682,14 @@ impl ScriptTask {
|
|||
|
||||
let context = Arc::new(Mutex::new(ParserContext::new(id, subpage, script_chan.clone(),
|
||||
load_data.url.clone())));
|
||||
let (action_sender, action_receiver) = channel();
|
||||
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
||||
let listener = box NetworkListener {
|
||||
context: context,
|
||||
script_chan: script_chan.clone(),
|
||||
receiver: action_receiver,
|
||||
};
|
||||
thread::spawn(move || listener.run());
|
||||
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
|
||||
listener.notify(message.to().unwrap());
|
||||
});
|
||||
let response_target = AsyncResponseTarget {
|
||||
sender: action_sender,
|
||||
};
|
||||
|
@ -1703,10 +1699,10 @@ impl ScriptTask {
|
|||
}
|
||||
|
||||
resource_task.send(ControlMsg::Load(NetLoadData {
|
||||
url: SerializableUrl(load_data.url),
|
||||
method: SerializableMethod(load_data.method),
|
||||
headers: SerializableHeaders(Headers::new()),
|
||||
preserved_headers: SerializableHeaders(load_data.headers),
|
||||
url: load_data.url,
|
||||
method: load_data.method,
|
||||
headers: Headers::new(),
|
||||
preserved_headers: load_data.headers,
|
||||
data: load_data.data,
|
||||
cors: None,
|
||||
pipeline_id: Some(id),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue