From 6dd7af2bdaa45f1f6fa70447f832db90a4aa35e2 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 17 Nov 2017 14:57:07 -0800 Subject: [PATCH] Fetch cancellation: Add CancellationListener --- components/net/fetch/methods.rs | 32 +++++++++++++++++++++++++++++-- components/net/resource_thread.rs | 6 +++--- tests/unit/net/fetch.rs | 4 ++-- tests/unit/net/lib.rs | 6 +++--- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs index 789501fa3223..f65c6c196f2e 100644 --- a/components/net/fetch/methods.rs +++ b/components/net/fetch/methods.rs @@ -28,7 +28,7 @@ use std::fs::File; use std::io::Read; use std::mem; use std::str; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::sync::mpsc::{Sender, Receiver}; use subresource_integrity::is_response_integrity_valid; @@ -44,9 +44,37 @@ pub struct FetchContext { pub user_agent: Cow<'static, str>, pub devtools_chan: Option>, pub filemanager: FileManager, - pub cancel_chan: Option>, + pub cancellation_listener: Arc>, } +pub struct CancellationListener { + cancel_chan: Option>, + cancelled: bool, +} + +impl CancellationListener { + pub fn new(cancel_chan: Option>) -> Self { + Self { + cancel_chan: cancel_chan, + cancelled: false, + } + } + + pub fn cancelled(&mut self) -> bool { + if let Some(ref cancel_chan) = self.cancel_chan { + if self.cancelled { + true + } else if cancel_chan.try_recv().is_ok() { + self.cancelled = true; + true + } else { + false + } + } else { + false + } + } +} pub type DoneChannel = Option<(Sender, Receiver)>; /// [Fetch](https://fetch.spec.whatwg.org#concept-fetch) diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs index 8837ae64bf80..4e9a691751f3 100644 --- a/components/net/resource_thread.rs +++ b/components/net/resource_thread.rs @@ -9,7 +9,7 @@ use cookie_rs; use cookie_storage::CookieStorage; use devtools_traits::DevtoolsControlMsg; use fetch::cors_cache::CorsCache; -use fetch::methods::{FetchContext, fetch}; +use fetch::methods::{CancellationListener, FetchContext, fetch}; use filemanager_thread::{FileManager, TFDProvider}; use hsts::HstsList; use http_loader::{HttpState, http_redirect_fetch}; @@ -35,7 +35,7 @@ use std::fs::File; use std::io::prelude::*; use std::ops::Deref; use std::path::{Path, PathBuf}; -use std::sync::{Arc, RwLock}; +use std::sync::{Arc, Mutex, RwLock}; use std::sync::mpsc::Sender; use std::thread; use storage_thread::StorageThreadFactory; @@ -347,7 +347,7 @@ impl CoreResourceManager { user_agent: ua, devtools_chan: dc, filemanager: filemanager, - cancel_chan: cancel_chan, + cancellation_listener: Arc::new(Mutex::new(CancellationListener::new(cancel_chan))), }; match res_init_ { diff --git a/tests/unit/net/fetch.rs b/tests/unit/net/fetch.rs index 3508942dac33..7d3a85de763f 100644 --- a/tests/unit/net/fetch.rs +++ b/tests/unit/net/fetch.rs @@ -25,7 +25,7 @@ use hyper_openssl; use msg::constellation_msg::TEST_PIPELINE_ID; use net::connector::create_ssl_client; use net::fetch::cors_cache::CorsCache; -use net::fetch::methods::FetchContext; +use net::fetch::methods::{CancellationListener, FetchContext}; use net::filemanager_thread::FileManager; use net::hsts::HstsEntry; use net::test::HttpState; @@ -538,7 +538,7 @@ fn test_fetch_with_hsts() { user_agent: DEFAULT_USER_AGENT.into(), devtools_chan: None, filemanager: FileManager::new(), - cancel_chan: None, + cancellation_listener: Arc::new(Mutex::new(CancellationListener::new(None))), }; { diff --git a/tests/unit/net/lib.rs b/tests/unit/net/lib.rs index bb5aed81fb32..497db8f6b302 100644 --- a/tests/unit/net/lib.rs +++ b/tests/unit/net/lib.rs @@ -36,7 +36,7 @@ use devtools_traits::DevtoolsControlMsg; use hyper::server::{Handler, Listening, Server}; use net::connector::create_ssl_client; use net::fetch::cors_cache::CorsCache; -use net::fetch::methods::{self, FetchContext}; +use net::fetch::methods::{self, CancellationListener, FetchContext}; use net::filemanager_thread::FileManager; use net::test::HttpState; use net_traits::FetchTaskTarget; @@ -44,7 +44,7 @@ use net_traits::request::Request; use net_traits::response::Response; use servo_config::resource_files::resources_dir_path; use servo_url::ServoUrl; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::sync::mpsc::{Sender, channel}; const DEFAULT_USER_AGENT: &'static str = "Such Browser. Very Layout. Wow."; @@ -61,7 +61,7 @@ fn new_fetch_context(dc: Option>) -> FetchContext { user_agent: DEFAULT_USER_AGENT.into(), devtools_chan: dc, filemanager: FileManager::new(), - cancel_chan: None, + cancellation_listener: Arc::new(Mutex::new(CancellationListener::new(None))), } } impl FetchTaskTarget for FetchResponseCollector {