Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make AsyncResponseListener methods take `&mut self` #8043

Merged
merged 2 commits into from Oct 16, 2015
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -163,13 +163,13 @@ pub trait AsyncFetchListener {
/// A listener for asynchronous network events. Cancelling the underlying request is unsupported.
pub trait AsyncResponseListener {
/// The response headers for a request have been received.
fn headers_available(&self, metadata: Metadata);
fn headers_available(&mut self, metadata: Metadata);
/// A portion of the response body has been received. This data is unavailable after
/// this method returned, and must be stored accordingly.
fn data_available(&self, payload: Vec<u8>);
fn data_available(&mut self, payload: Vec<u8>);
/// The response is complete. If the provided status is an Err value, there is no guarantee
/// that the response body was completely read.
fn response_complete(&self, status: Result<(), String>);
fn response_complete(&mut self, status: Result<(), String>);
}

/// Data for passing between threads/processes to indicate a particular action to
@@ -186,7 +186,7 @@ pub enum ResponseAction {

impl ResponseAction {
/// Execute the default action on a provided listener.
pub fn process(self, listener: &AsyncResponseListener) {
pub fn process(self, listener: &mut AsyncResponseListener) {
match self {
ResponseAction::HeadersAvailable(m) => listener.headers_available(m),
ResponseAction::DataAvailable(d) => listener.data_available(d),
@@ -23,7 +23,6 @@ use network_listener::{NetworkListener, PreInvoke};
use script_task::ScriptChan;
use std::ascii::AsciiExt;
use std::borrow::ToOwned;
use std::cell::RefCell;
use std::sync::{Arc, Mutex};
use time::{self, Timespec, now};
use unicase::UniCase;
@@ -106,28 +105,28 @@ impl CORSRequest {
script_chan: Box<ScriptChan + Send>) {
struct CORSContext {
listener: Box<AsyncCORSResponseListener + Send>,
response: RefCell<Option<CORSResponse>>,
response: Option<CORSResponse>,
}

// This is shoe-horning the CORSReponse stuff into the rest of the async network
// framework right now. It would be worth redesigning http_fetch to do this properly.
impl AsyncResponseListener for CORSContext {
fn headers_available(&self, _metadata: Metadata) {
fn headers_available(&mut self, _metadata: Metadata) {
}

fn data_available(&self, _payload: Vec<u8>) {
fn data_available(&mut self, _payload: Vec<u8>) {
}

fn response_complete(&self, _status: Result<(), String>) {
let response = self.response.borrow_mut().take().unwrap();
fn response_complete(&mut self, _status: Result<(), String>) {
let response = self.response.take().unwrap();
self.listener.response_available(response);
}
}
impl PreInvoke for CORSContext {}

let context = CORSContext {
listener: listener,
response: RefCell::new(None),
response: None,
};
let listener = NetworkListener {
context: Arc::new(Mutex::new(context)),
@@ -141,7 +140,7 @@ impl CORSRequest {
let response = req.http_fetch();
let mut context = listener.context.lock();
let context = context.as_mut().unwrap();
*context.response.borrow_mut() = Some(response);
context.response = Some(response);
listener.notify(ResponseAction::ResponseComplete(Ok(())));
});
}
@@ -38,7 +38,7 @@ use network_listener::{NetworkListener, PreInvoke};
use script_task::ScriptTaskEventCategory::ScriptEvent;
use script_task::{CommonScriptMsg, Runnable, ScriptChan};
use std::ascii::AsciiExt;
use std::cell::{Cell, RefCell};
use std::cell::Cell;
use std::mem;
use std::sync::{Arc, Mutex};
use url::{Url, UrlParser};
@@ -128,29 +128,29 @@ struct ScriptContext {
/// The element that initiated the request.
elem: Trusted<HTMLScriptElement>,
/// The response body received to date.
data: RefCell<Vec<u8>>,
data: Vec<u8>,
/// The response metadata received to date.
metadata: RefCell<Option<Metadata>>,
metadata: Option<Metadata>,
/// Whether the owning document's parser should resume once the response completes.
resume_on_completion: bool,
/// The initial URL requested.
url: Url,
}

impl AsyncResponseListener for ScriptContext {
fn headers_available(&self, metadata: Metadata) {
*self.metadata.borrow_mut() = Some(metadata);
fn headers_available(&mut self, metadata: Metadata) {
self.metadata = Some(metadata);
}

fn data_available(&self, payload: Vec<u8>) {
fn data_available(&mut self, payload: Vec<u8>) {
let mut payload = payload;
self.data.borrow_mut().append(&mut payload);
self.data.append(&mut payload);
}

fn response_complete(&self, status: Result<(), String>) {
fn response_complete(&mut self, status: Result<(), String>) {
let load = status.map(|_| {
let data = mem::replace(&mut *self.data.borrow_mut(), vec!());
let metadata = self.metadata.borrow_mut().take().unwrap();
let data = mem::replace(&mut self.data, vec!());
let metadata = self.metadata.take().unwrap();
(metadata, data)
});
let elem = self.elem.root();
@@ -283,8 +283,8 @@ impl HTMLScriptElement {

let context = Arc::new(Mutex::new(ScriptContext {
elem: elem,
data: RefCell::new(vec!()),
metadata: RefCell::new(None),
data: vec!(),
metadata: None,
resume_on_completion: self.parser_inserted.get(),
url: url.clone(),
}));
@@ -31,7 +31,7 @@ use net_traits::{AsyncResponseListener, Metadata};
use network_listener::PreInvoke;
use parse::Parser;
use script_task::{ScriptChan, ScriptTask};
use std::cell::{Cell, RefCell};
use std::cell::Cell;
use std::default::Default;
use url::Url;

@@ -69,9 +69,9 @@ pub type Tokenizer = tokenizer::Tokenizer<TreeBuilder<JS<Node>, Sink>>;
/// The context required for asynchronously fetching a document and parsing it progressively.
pub struct ParserContext {
/// The parser that initiated the request.
parser: RefCell<Option<Trusted<ServoHTMLParser>>>,
parser: Option<Trusted<ServoHTMLParser>>,
/// Is this document a synthesized document for a single image?
is_image_document: Cell<bool>,
is_image_document: bool,
/// The pipeline associated with this document.
id: PipelineId,
/// The subpage associated with this document.
@@ -86,8 +86,8 @@ impl ParserContext {
pub fn new(id: PipelineId, subpage: Option<SubpageId>, script_chan: Box<ScriptChan + Send>,
url: Url) -> ParserContext {
ParserContext {
parser: RefCell::new(None),
is_image_document: Cell::new(false),
parser: None,
is_image_document: false,
id: id,
subpage: subpage,
script_chan: script_chan,
@@ -97,7 +97,7 @@ impl ParserContext {
}

impl AsyncResponseListener for ParserContext {
fn headers_available(&self, metadata: Metadata) {
fn headers_available(&mut self, metadata: Metadata) {
let content_type = metadata.content_type.clone();

let parser = ScriptTask::page_fetch_complete(self.id.clone(), self.subpage.clone(),
@@ -109,12 +109,11 @@ impl AsyncResponseListener for ParserContext {

let parser = parser.r();
let win = parser.window();
*self.parser.borrow_mut() = Some(Trusted::new(win.r().get_cx(), parser,
self.script_chan.clone()));
self.parser = Some(Trusted::new(win.r().get_cx(), parser, self.script_chan.clone()));

match content_type {
Some(ContentType(Mime(TopLevel::Image, _, _))) => {
self.is_image_document.set(true);
self.is_image_document = true;
let page = format!("<html><body><img src='{}' /></body></html>",
self.url.serialize());
parser.pending_input.borrow_mut().push(page);
@@ -137,20 +136,20 @@ impl AsyncResponseListener for ParserContext {
}
}

fn data_available(&self, payload: Vec<u8>) {
if !self.is_image_document.get() {
fn data_available(&mut self, payload: Vec<u8>) {
if !self.is_image_document {
// FIXME: use Vec<u8> (html5ever #34)
let data = UTF_8.decode(&payload, DecoderTrap::Replace).unwrap();
let parser = match self.parser.borrow().as_ref() {
let parser = match self.parser.as_ref() {
Some(parser) => parser.root(),
None => return,
};
parser.r().parse_chunk(data);
}
}

fn response_complete(&self, status: Result<(), String>) {
let parser = match self.parser.borrow().as_ref() {
fn response_complete(&mut self, status: Result<(), String>) {
let parser = match self.parser.as_ref() {
Some(parser) => parser.root(),
None => return,
};
@@ -237,7 +237,7 @@ impl XMLHttpRequest {
resource_task: ResourceTask,
load_data: LoadData) {
impl AsyncResponseListener for XHRContext {
fn headers_available(&self, metadata: Metadata) {
fn headers_available(&mut self, metadata: Metadata) {
let xhr = self.xhr.root();
let rv = xhr.r().process_headers_available(self.cors_request.clone(),
self.gen_id,
@@ -247,13 +247,13 @@ impl XMLHttpRequest {
}
}

fn data_available(&self, payload: Vec<u8>) {
fn data_available(&mut self, payload: Vec<u8>) {
self.buf.borrow_mut().push_all(&payload);
let xhr = self.xhr.root();
xhr.r().process_data_available(self.gen_id, self.buf.borrow().clone());
}

fn response_complete(&self, status: Result<(), String>) {
fn response_complete(&mut self, status: Result<(), String>) {
let xhr = self.xhr.root();
let rv = xhr.r().process_response_complete(self.gen_id, status);
*self.sync_status.borrow_mut() = Some(rv);
@@ -43,9 +43,9 @@ struct ListenerRunnable<T: AsyncResponseListener + PreInvoke + Send> {
impl<T: AsyncResponseListener + PreInvoke + Send> Runnable for ListenerRunnable<T> {
fn handler(self: Box<ListenerRunnable<T>>) {
let this = *self;
let context = this.context.lock().unwrap();
let mut context = this.context.lock().unwrap();
if context.should_invoke() {
this.action.process(&*context);
this.action.process(&mut *context);
}
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.