diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 12e4d9916e09..dc28056e81bb 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -30,7 +30,6 @@ use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData}; use msg::constellation_msg::{PipelineNamespace, PipelineNamespaceId, TraversalDirection}; use msg::constellation_msg::{SubpageId, WindowSizeType}; use net_traits::bluetooth_thread::BluetoothMethodMsg; -use net_traits::filemanager_thread::FileManagerThreadMsg; use net_traits::image_cache_thread::ImageCacheThread; use net_traits::storage_thread::StorageThreadMsg; use net_traits::{self, ResourceThreads, IpcSend}; @@ -1042,11 +1041,6 @@ impl Constellation warn!("Exit storage thread failed ({})", e); } - debug!("Exiting file manager resource threads."); - if let Err(e) = self.public_resource_threads.send(FileManagerThreadMsg::Exit) { - warn!("Exit storage thread failed ({})", e); - } - debug!("Exiting bluetooth thread."); if let Err(e) = self.bluetooth_thread.send(BluetoothMethodMsg::Exit) { warn!("Exit bluetooth thread failed ({})", e); diff --git a/components/net/blob_loader.rs b/components/net/blob_loader.rs index d8e4e6663e85..0783afd979ab 100644 --- a/components/net/blob_loader.rs +++ b/components/net/blob_loader.rs @@ -2,10 +2,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use filemanager_thread::{FileManager, UIProvider}; use hyper::header::{DispositionType, ContentDisposition, DispositionParam}; use hyper::header::{Headers, ContentType, ContentLength, Charset}; use hyper::http::RawStatus; -use ipc_channel::ipc::{self, IpcSender}; +use ipc_channel::ipc; use mime::{Mime, Attr}; use mime_classifier::MimeClassifier; use net_traits::ProgressMsg::{Payload, Done}; @@ -22,29 +23,26 @@ use util::thread::spawn_named; // TODO: Check on GET // https://w3c.github.io/FileAPI/#requestResponseModel -pub fn factory(filemanager_chan: IpcSender) - -> Box, - CancellationListener) + Send> { +pub fn factory(filemanager: Arc>) + -> Box, CancellationListener) + Send> { box move |load_data: LoadData, start_chan, classifier, cancel_listener| { spawn_named(format!("blob loader for {}", load_data.url), move || { - load_blob(load_data, start_chan, classifier, filemanager_chan, cancel_listener); + load_blob(load_data, start_chan, classifier, filemanager, cancel_listener); }) } } -fn load_blob(load_data: LoadData, start_chan: LoadConsumer, +fn load_blob + (load_data: LoadData, start_chan: LoadConsumer, classifier: Arc, - filemanager_chan: IpcSender, - // XXX(izgzhen): we should utilize cancel_listener, filed in #12589 - _cancel_listener: CancellationListener) { + filemanager: Arc>, + cancel_listener: CancellationListener) { let (chan, recv) = ipc::channel().unwrap(); if let Ok((id, origin, _fragment)) = parse_blob_url(&load_data.url.clone()) { let id = SelectedFileId(id.simple().to_string()); let check_url_validity = true; let msg = FileManagerThreadMsg::ReadFile(chan, id, check_url_validity, origin); - let _ = filemanager_chan.send(msg); + let _ = filemanager.handle(msg, Some(cancel_listener)); // Receive first chunk match recv.recv().unwrap() { diff --git a/components/net/filemanager_thread.rs b/components/net/filemanager_thread.rs index 10989f1a0cb5..5f9e6654bed8 100644 --- a/components/net/filemanager_thread.rs +++ b/components/net/filemanager_thread.rs @@ -2,12 +2,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; +use ipc_channel::ipc::IpcSender; use mime_guess::guess_mime_type_opt; use net_traits::blob_url_store::{BlobBuf, BlobURLStoreError}; use net_traits::filemanager_thread::{FileManagerThreadMsg, FileManagerResult, FilterPattern, FileOrigin}; use net_traits::filemanager_thread::{SelectedFile, RelativePos, FileManagerThreadError}; use net_traits::filemanager_thread::{SelectedFileId, ReadFileProgress}; +use resource_thread::CancellationListener; use std::collections::HashMap; use std::fs::File; use std::io::{Read, Seek, SeekFrom}; @@ -22,10 +23,6 @@ use util::prefs::PREFS; use util::thread::spawn_named; use uuid::Uuid; -pub trait FileManagerThreadFactory { - fn new(&'static UI) -> Self; -} - /// Trait that provider of file-dialog UI should implement. /// It will be used to initialize a generic FileManager. /// For example, we can choose a dummy UI for testing purpose. @@ -79,19 +76,6 @@ impl UIProvider for TFDProvider { } } -impl FileManagerThreadFactory for IpcSender { - /// Create a FileManagerThread - fn new(ui: &'static UI) -> IpcSender { - let (chan, recv) = ipc::channel().unwrap(); - - spawn_named("FileManager".to_owned(), move || { - FileManager::new(recv, ui).start(); - }); - - chan - } -} - /// FileManagerStore's entry struct FileStoreEntry { /// Origin of the entry's "creator" @@ -127,83 +111,79 @@ enum FileImpl { Sliced(Uuid, RelativePos), } -struct FileManager { - receiver: IpcReceiver, +pub struct FileManager { store: Arc>, } impl FileManager { - fn new(recv: IpcReceiver, ui: &'static UI) -> FileManager { + pub fn new(ui: &'static UI) -> FileManager { FileManager { - receiver: recv, store: Arc::new(FileManagerStore::new(ui)), } } - /// Start the file manager event loop - fn start(&mut self) { - loop { - let store = self.store.clone(); - match self.receiver.recv().unwrap() { - FileManagerThreadMsg::SelectFile(filter, sender, origin, opt_test_path) => { - spawn_named("select file".to_owned(), move || { - store.select_file(filter, sender, origin, opt_test_path); - }); - } - FileManagerThreadMsg::SelectFiles(filter, sender, origin, opt_test_paths) => { - spawn_named("select files".to_owned(), move || { - store.select_files(filter, sender, origin, opt_test_paths); - }) - } - FileManagerThreadMsg::ReadFile(sender, id, check_url_validity, origin) => { - spawn_named("read file".to_owned(), move || { - if let Err(e) = store.try_read_file(sender.clone(), id, check_url_validity, origin) { - let _ = sender.send(Err(FileManagerThreadError::BlobURLStoreError(e))); - } - }) - } - FileManagerThreadMsg::PromoteMemory(blob_buf, set_valid, sender, origin) => { - spawn_named("transfer memory".to_owned(), move || { - store.promote_memory(blob_buf, set_valid, sender, origin); + /// Message handler + pub fn handle(&self, msg: FileManagerThreadMsg, cancel_listener: Option) { + let store = self.store.clone(); + match msg { + FileManagerThreadMsg::SelectFile(filter, sender, origin, opt_test_path) => { + spawn_named("select file".to_owned(), move || { + store.select_file(filter, sender, origin, opt_test_path); + }); + } + FileManagerThreadMsg::SelectFiles(filter, sender, origin, opt_test_paths) => { + spawn_named("select files".to_owned(), move || { + store.select_files(filter, sender, origin, opt_test_paths); + }) + } + FileManagerThreadMsg::ReadFile(sender, id, check_url_validity, origin) => { + spawn_named("read file".to_owned(), move || { + if let Err(e) = store.try_read_file(sender.clone(), id, check_url_validity, + origin, cancel_listener) { + let _ = sender.send(Err(FileManagerThreadError::BlobURLStoreError(e))); + } + }) + } + FileManagerThreadMsg::PromoteMemory(blob_buf, set_valid, sender, origin) => { + spawn_named("transfer memory".to_owned(), move || { + store.promote_memory(blob_buf, set_valid, sender, origin); + }) + } + FileManagerThreadMsg::AddSlicedURLEntry(id, rel_pos, sender, origin) =>{ + spawn_named("add sliced URL entry".to_owned(), move || { + store.add_sliced_url_entry(id, rel_pos, sender, origin); + }) + } + FileManagerThreadMsg::DecRef(id, origin, sender) => { + if let Ok(id) = Uuid::parse_str(&id.0) { + spawn_named("dec ref".to_owned(), move || { + // Since it is simple DecRef (possibly caused by close/drop), + // unset_url_validity is false + let _ = sender.send(store.dec_ref(&id, &origin)); }) + } else { + let _ = sender.send(Err(BlobURLStoreError::InvalidFileID)); } - FileManagerThreadMsg::AddSlicedURLEntry(id, rel_pos, sender, origin) =>{ - spawn_named("add sliced URL entry".to_owned(), move || { - store.add_sliced_url_entry(id, rel_pos, sender, origin); + } + FileManagerThreadMsg::RevokeBlobURL(id, origin, sender) => { + if let Ok(id) = Uuid::parse_str(&id.0) { + spawn_named("revoke blob url".to_owned(), move || { + // Since it is revocation, unset_url_validity is true + let _ = sender.send(store.set_blob_url_validity(false, &id, &origin)); }) + } else { + let _ = sender.send(Err(BlobURLStoreError::InvalidFileID)); } - FileManagerThreadMsg::RevokeBlobURL(id, origin, sender) => { - if let Ok(id) = Uuid::parse_str(&id.0) { - spawn_named("revoke blob url".to_owned(), move || { - // Since it is revocation, unset_url_validity is true - let _ = sender.send(store.set_blob_url_validity(false, &id, &origin)); - }) - } else { - let _ = sender.send(Err(BlobURLStoreError::InvalidFileID)); - } - } - FileManagerThreadMsg::DecRef(id, origin, sender) => { - if let Ok(id) = Uuid::parse_str(&id.0) { - spawn_named("dec ref".to_owned(), move || { - // Since it is simple DecRef (possibly caused by close/drop), - // unset_url_validity is false - let _ = sender.send(store.dec_ref(&id, &origin)); - }) - } else { - let _ = sender.send(Err(BlobURLStoreError::InvalidFileID)); - } - } - FileManagerThreadMsg::ActivateBlobURL(id, sender, origin) => { - if let Ok(id) = Uuid::parse_str(&id.0) { - spawn_named("activate blob url".to_owned(), move || { - let _ = sender.send(store.set_blob_url_validity(true, &id, &origin)); - }); - } else { - let _ = sender.send(Err(BlobURLStoreError::InvalidFileID)); - } + } + FileManagerThreadMsg::ActivateBlobURL(id, sender, origin) => { + if let Ok(id) = Uuid::parse_str(&id.0) { + spawn_named("activate blob url".to_owned(), move || { + let _ = sender.send(store.set_blob_url_validity(true, &id, &origin)); + }); + } else { + let _ = sender.send(Err(BlobURLStoreError::InvalidFileID)); } - FileManagerThreadMsg::Exit => break, - }; + } } } } @@ -405,7 +385,8 @@ impl FileManagerStore { fn get_blob_buf(&self, sender: IpcSender>, id: &Uuid, origin_in: &FileOrigin, rel_pos: RelativePos, - check_url_validity: bool) -> Result<(), BlobURLStoreError> { + check_url_validity: bool, + cancel_listener: Option) -> Result<(), BlobURLStoreError> { let file_impl = try!(self.get_impl(id, origin_in, check_url_validity)); match file_impl { FileImpl::Memory(buf) => { @@ -437,7 +418,7 @@ impl FileManagerStore { let range = rel_pos.to_abs_range(metadata.size as usize); let mut file = try!(File::open(&metadata.path) - .map_err(|e| BlobURLStoreError::External(e.to_string()))); + .map_err(|e| BlobURLStoreError::External(e.to_string()))); let seeked_start = try!(file.seek(SeekFrom::Start(range.start as u64)) .map_err(|e| BlobURLStoreError::External(e.to_string()))); @@ -447,7 +428,8 @@ impl FileManagerStore { None => "".to_string(), }; - chunked_read(sender, &mut file, range.len(), opt_filename, type_string); + chunked_read(sender, &mut file, range.len(), opt_filename, + type_string, cancel_listener); Ok(()) } else { Err(BlobURLStoreError::InvalidEntry) @@ -456,17 +438,20 @@ impl FileManagerStore { FileImpl::Sliced(parent_id, inner_rel_pos) => { // Next time we don't need to check validity since // we have already done that for requesting URL if necessary - self.get_blob_buf(sender, &parent_id, origin_in, rel_pos.slice_inner(&inner_rel_pos), false) + self.get_blob_buf(sender, &parent_id, origin_in, + rel_pos.slice_inner(&inner_rel_pos), false, + cancel_listener) } } } // Convenient wrapper over get_blob_buf fn try_read_file(&self, sender: IpcSender>, - id: SelectedFileId, check_url_validity: bool, - origin_in: FileOrigin) -> Result<(), BlobURLStoreError> { + id: SelectedFileId, check_url_validity: bool, origin_in: FileOrigin, + cancel_listener: Option) -> Result<(), BlobURLStoreError> { let id = try!(Uuid::parse_str(&id.0).map_err(|_| BlobURLStoreError::InvalidFileID)); - self.get_blob_buf(sender, &id, &origin_in, RelativePos::full_range(), check_url_validity) + self.get_blob_buf(sender, &id, &origin_in, RelativePos::full_range(), + check_url_validity, cancel_listener) } fn dec_ref(&self, id: &Uuid, origin_in: &FileOrigin) -> Result<(), BlobURLStoreError> { @@ -580,7 +565,8 @@ fn select_files_pref_enabled() -> bool { const CHUNK_SIZE: usize = 8192; fn chunked_read(sender: IpcSender>, - file: &mut File, size: usize, opt_filename: Option, type_string: String) { + file: &mut File, size: usize, opt_filename: Option, + type_string: String, cancel_listener: Option) { // First chunk let mut buf = vec![0; CHUNK_SIZE]; match file.read(&mut buf) { @@ -602,6 +588,12 @@ fn chunked_read(sender: IpcSender>, // Send the remaining chunks loop { + if let Some(ref listener) = cancel_listener.as_ref() { + if listener.is_cancelled() { + break; + } + } + let mut buf = vec![0; CHUNK_SIZE]; match file.read(&mut buf) { Ok(0) => { diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs index b24e1bbe7bf2..411b0d223736 100644 --- a/components/net/resource_thread.rs +++ b/components/net/resource_thread.rs @@ -15,7 +15,7 @@ use data_loader; use devtools_traits::DevtoolsControlMsg; use fetch::methods::{fetch, FetchContext}; use file_loader; -use filemanager_thread::{FileManagerThreadFactory, TFDProvider}; +use filemanager_thread::{FileManager, TFDProvider}; use hsts::HstsList; use http_loader::{self, HttpState}; use hyper::client::pool::Pool; @@ -25,7 +25,6 @@ use ipc_channel::ipc::{self, IpcReceiver, IpcSender, IpcReceiverSet}; use mime_classifier::{ApacheBugFlag, MimeClassifier, NoSniffFlag}; use net_traits::LoadContext; use net_traits::ProgressMsg::Done; -use net_traits::filemanager_thread::FileManagerThreadMsg; use net_traits::request::{Request, RequestInit}; use net_traits::storage_thread::StorageThreadMsg; use net_traits::{AsyncResponseTarget, Metadata, ProgressMsg, ResponseAction, CoreResourceThread}; @@ -168,16 +167,14 @@ pub fn new_resource_threads(user_agent: String, profiler_chan: ProfilerChan, config_dir: Option) -> (ResourceThreads, ResourceThreads) { - let filemanager_chan: IpcSender = FileManagerThreadFactory::new(TFD_PROVIDER); let (public_core, private_core) = new_core_resource_thread( user_agent, devtools_chan, profiler_chan, - filemanager_chan.clone(), config_dir.clone()); let storage: IpcSender = StorageThreadFactory::new(config_dir); - (ResourceThreads::new(public_core, storage.clone(), filemanager_chan.clone()), - ResourceThreads::new(private_core, storage, filemanager_chan)) + (ResourceThreads::new(public_core, storage.clone()), + ResourceThreads::new(private_core, storage)) } @@ -185,7 +182,6 @@ pub fn new_resource_threads(user_agent: String, pub fn new_core_resource_thread(user_agent: String, devtools_chan: Option>, profiler_chan: ProfilerChan, - filemanager_chan: IpcSender, config_dir: Option) -> (CoreResourceThread, CoreResourceThread) { let (public_setup_chan, public_setup_port) = ipc::channel().unwrap(); @@ -194,7 +190,7 @@ pub fn new_core_resource_thread(user_agent: String, let private_setup_chan_clone = private_setup_chan.clone(); spawn_named("ResourceManager".to_owned(), move || { let resource_manager = CoreResourceManager::new( - user_agent, devtools_chan, profiler_chan, filemanager_chan + user_agent, devtools_chan, profiler_chan ); let mut channel_manager = ResourceChannelManager { @@ -307,6 +303,7 @@ impl ResourceChannelManager { CoreResourceMsg::Synchronize(sender) => { let _ = sender.send(()); } + CoreResourceMsg::ToFileManager(msg) => self.resource_manager.filemanager.handle(msg, None), CoreResourceMsg::Exit(sender) => { if let Some(ref config_dir) = self.config_dir { match group.auth_cache.read() { @@ -476,7 +473,7 @@ pub struct CoreResourceManager { devtools_chan: Option>, swmanager_chan: Option>, profiler_chan: ProfilerChan, - filemanager_chan: IpcSender, + filemanager: Arc>, cancel_load_map: HashMap>, next_resource_id: ResourceId, } @@ -484,15 +481,14 @@ pub struct CoreResourceManager { impl CoreResourceManager { pub fn new(user_agent: String, devtools_channel: Option>, - profiler_chan: ProfilerChan, - filemanager_chan: IpcSender) -> CoreResourceManager { + profiler_chan: ProfilerChan) -> CoreResourceManager { CoreResourceManager { user_agent: user_agent, mime_classifier: Arc::new(MimeClassifier::new()), devtools_chan: devtools_channel, swmanager_chan: None, profiler_chan: profiler_chan, - filemanager_chan: filemanager_chan, + filemanager: Arc::new(FileManager::new(TFD_PROVIDER)), cancel_load_map: HashMap::new(), next_resource_id: ResourceId(0), } @@ -567,7 +563,7 @@ impl CoreResourceManager { }, "data" => from_factory(data_loader::factory), "about" => from_factory(about_loader::factory), - "blob" => blob_loader::factory(self.filemanager_chan.clone()), + "blob" => blob_loader::factory(self.filemanager.clone()), _ => { debug!("resource_thread: no loader for scheme {}", load_data.url.scheme()); send_error(load_data.url, NetworkError::Internal("no loader for scheme".to_owned()), consumer); diff --git a/components/net_traits/filemanager_thread.rs b/components/net_traits/filemanager_thread.rs index d648ec230838..8ea607f191fc 100644 --- a/components/net_traits/filemanager_thread.rs +++ b/components/net_traits/filemanager_thread.rs @@ -146,9 +146,6 @@ pub enum FileManagerThreadMsg { /// Revoke Blob URL and send back the acknowledgement RevokeBlobURL(SelectedFileId, FileOrigin, IpcSender>), - - /// Shut down this thread - Exit, } #[derive(Debug, Deserialize, Serialize)] diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index 8e7bb996697d..fd2973033ebc 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -321,17 +321,14 @@ pub trait IpcSend where T: serde::Serialize + serde::Deserialize { pub struct ResourceThreads { core_thread: CoreResourceThread, storage_thread: IpcSender, - filemanager_thread: IpcSender, } impl ResourceThreads { pub fn new(c: CoreResourceThread, - s: IpcSender, - f: IpcSender) -> ResourceThreads { + s: IpcSender) -> ResourceThreads { ResourceThreads { core_thread: c, storage_thread: s, - filemanager_thread: f, } } } @@ -356,16 +353,6 @@ impl IpcSend for ResourceThreads { } } -impl IpcSend for ResourceThreads { - fn send(&self, msg: FileManagerThreadMsg) -> IpcSendResult { - self.filemanager_thread.send(msg) - } - - fn sender(&self) -> IpcSender { - self.filemanager_thread.clone() - } -} - // Ignore the sub-fields impl HeapSizeOf for ResourceThreads { fn heap_size_of_children(&self) -> usize { 0 } @@ -431,6 +418,8 @@ pub enum CoreResourceMsg { Synchronize(IpcSender<()>), /// Send the network sender in constellation to CoreResourceThread NetworkMediator(IpcSender), + /// Message forwarded to file manager's handler + ToFileManager(FileManagerThreadMsg), /// Break the load handler loop, send a reply when done cleaning up local resources // and exit Exit(IpcSender<()>), diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs index fe81b8a14dee..bfc3212a9c45 100644 --- a/components/script/dom/bindings/global.rs +++ b/components/script/dom/bindings/global.rs @@ -19,7 +19,6 @@ use js::jsapi::{CurrentGlobalOrNull, GetGlobalForObjectCrossCompartment}; use js::jsapi::{JSContext, JSObject, JS_GetClass, MutableHandleValue}; use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL}; use msg::constellation_msg::PipelineId; -use net_traits::filemanager_thread::FileManagerThreadMsg; use net_traits::{ResourceThreads, CoreResourceThread, IpcSend}; use profile_traits::{mem, time}; use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort}; @@ -133,11 +132,6 @@ impl<'a> GlobalRef<'a> { self.resource_threads().sender() } - /// Get the port to file manager for this global scope - pub fn filemanager_thread(&self) -> IpcSender { - self.resource_threads().sender() - } - /// Get the worker's id. pub fn get_worker_id(&self) -> Option { match *self { diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index 2f3865b7ce09..4711da800108 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -14,9 +14,9 @@ use dom::bindings::str::DOMString; use encoding::all::UTF_8; use encoding::types::{EncoderTrap, Encoding}; use ipc_channel::ipc; -use net_traits::IpcSend; use net_traits::blob_url_store::{BlobBuf, get_blob_origin}; use net_traits::filemanager_thread::{FileManagerThreadMsg, SelectedFileId, RelativePos, ReadFileProgress}; +use net_traits::{CoreResourceMsg, IpcSend}; use std::cell::Cell; use std::mem; use std::ops::Index; @@ -197,11 +197,10 @@ impl Blob { if set_valid { let global = self.global(); let origin = get_blob_origin(&global.r().get_url()); - let filemanager = global.r().resource_threads().sender(); let (tx, rx) = ipc::channel().unwrap(); let msg = FileManagerThreadMsg::ActivateBlobURL(f.id.clone(), tx, origin.clone()); - let _ = filemanager.send(msg); + self.send_to_file_manager(msg); match rx.recv().unwrap() { Ok(_) => return f.id.clone(), @@ -218,7 +217,6 @@ impl Blob { let global = self.global(); let origin = get_blob_origin(&global.r().get_url()); - let filemanager = global.r().resource_threads().sender(); let blob_buf = BlobBuf { filename: None, @@ -228,7 +226,8 @@ impl Blob { }; let (tx, rx) = ipc::channel().unwrap(); - let _ = filemanager.send(FileManagerThreadMsg::PromoteMemory(blob_buf, set_valid, tx, origin.clone())); + let msg = FileManagerThreadMsg::PromoteMemory(blob_buf, set_valid, tx, origin.clone()); + self.send_to_file_manager(msg); match rx.recv().unwrap() { Ok(id) => { @@ -253,12 +252,11 @@ impl Blob { let origin = get_blob_origin(&global.r().get_url()); - let filemanager = global.r().resource_threads().sender(); let (tx, rx) = ipc::channel().unwrap(); let msg = FileManagerThreadMsg::AddSlicedURLEntry(parent_id.clone(), rel_pos.clone(), tx, origin.clone()); - let _ = filemanager.send(msg); + self.send_to_file_manager(msg); match rx.recv().expect("File manager thread is down") { Ok(new_id) => { let new_id = SelectedFileId(new_id.0); @@ -286,14 +284,19 @@ impl Blob { let global = self.global(); let origin = get_blob_origin(&global.r().get_url()); - let filemanager = global.r().resource_threads().sender(); let (tx, rx) = ipc::channel().unwrap(); let msg = FileManagerThreadMsg::DecRef(f.id.clone(), origin, tx); - let _ = filemanager.send(msg); + self.send_to_file_manager(msg); let _ = rx.recv().unwrap(); } } + + fn send_to_file_manager(&self, msg: FileManagerThreadMsg) { + let global = self.global(); + let resource_threads = global.r().resource_threads(); + let _ = resource_threads.send(CoreResourceMsg::ToFileManager(msg)); + } } impl Drop for Blob { @@ -305,12 +308,12 @@ impl Drop for Blob { } fn read_file(global: GlobalRef, id: SelectedFileId) -> Result, ()> { - let file_manager = global.filemanager_thread(); + let resource_threads = global.resource_threads(); let (chan, recv) = ipc::channel().map_err(|_|())?; let origin = get_blob_origin(&global.get_url()); let check_url_validity = false; let msg = FileManagerThreadMsg::ReadFile(chan, id, check_url_validity, origin); - let _ = file_manager.send(msg); + let _ = resource_threads.send(CoreResourceMsg::ToFileManager(msg)); let mut bytes = vec![]; diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 6f7a7a755f56..a98fcbcfb4e8 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -34,9 +34,9 @@ use dom::virtualmethods::VirtualMethods; use ipc_channel::ipc::{self, IpcSender}; use mime_guess; use msg::constellation_msg::Key; -use net_traits::IpcSend; use net_traits::blob_url_store::get_blob_origin; use net_traits::filemanager_thread::{FileManagerThreadMsg, FilterPattern}; +use net_traits::{IpcSend, CoreResourceMsg}; use script_traits::ScriptMsg as ConstellationMsg; use std::borrow::ToOwned; use std::cell::Cell; @@ -780,7 +780,7 @@ impl HTMLInputElement { fn select_files(&self, opt_test_paths: Option>) { let window = window_from_node(self); let origin = get_blob_origin(&window.get_url()); - let filemanager = window.resource_threads().sender(); + let resource_threads = window.resource_threads(); let mut files: Vec> = vec![]; let mut error = None; @@ -793,7 +793,7 @@ impl HTMLInputElement { let (chan, recv) = ipc::channel().expect("Error initializing channel"); let msg = FileManagerThreadMsg::SelectFiles(filter, chan, origin, opt_test_paths); - let _ = filemanager.send(msg).unwrap(); + let _ = resource_threads.send(CoreResourceMsg::ToFileManager(msg)).unwrap(); match recv.recv().expect("IpcSender side error") { Ok(selected_files) => { @@ -817,7 +817,7 @@ impl HTMLInputElement { let (chan, recv) = ipc::channel().expect("Error initializing channel"); let msg = FileManagerThreadMsg::SelectFile(filter, chan, origin, opt_test_path); - let _ = filemanager.send(msg).unwrap(); + let _ = resource_threads.send(CoreResourceMsg::ToFileManager(msg)).unwrap(); match recv.recv().expect("IpcSender side error") { Ok(selected) => { diff --git a/components/script/dom/url.rs b/components/script/dom/url.rs index 81c806de806d..768dabf1475b 100644 --- a/components/script/dom/url.rs +++ b/components/script/dom/url.rs @@ -14,9 +14,9 @@ use dom::blob::Blob; use dom::urlhelper::UrlHelper; use dom::urlsearchparams::URLSearchParams; use ipc_channel::ipc; -use net_traits::IpcSend; use net_traits::blob_url_store::{get_blob_origin, parse_blob_url}; use net_traits::filemanager_thread::{SelectedFileId, FileManagerThreadMsg}; +use net_traits::{IpcSend, CoreResourceMsg}; use std::borrow::ToOwned; use std::default::Default; use url::quirks::domain_to_unicode; @@ -145,11 +145,11 @@ impl URL { if let Ok(url) = Url::parse(&url) { if let Ok((id, _, _)) = parse_blob_url(&url) { - let filemanager = global.resource_threads().sender(); + let resource_threads = global.resource_threads(); let id = SelectedFileId(id.simple().to_string()); let (tx, rx) = ipc::channel().unwrap(); let msg = FileManagerThreadMsg::RevokeBlobURL(id, origin, tx); - let _ = filemanager.send(msg); + let _ = resource_threads.send(CoreResourceMsg::ToFileManager(msg)); let _ = rx.recv().unwrap(); } diff --git a/tests/unit/net/filemanager_thread.rs b/tests/unit/net/filemanager_thread.rs index d5ee2f6257bf..7266157481ac 100644 --- a/tests/unit/net/filemanager_thread.rs +++ b/tests/unit/net/filemanager_thread.rs @@ -2,8 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use ipc_channel::ipc::{self, IpcSender}; -use net::filemanager_thread::{FileManagerThreadFactory, UIProvider}; +use ipc_channel::ipc; +use net::filemanager_thread::{FileManager, UIProvider}; use net_traits::blob_url_store::BlobURLStoreError; use net_traits::filemanager_thread::{FilterPattern, FileManagerThreadMsg, FileManagerThreadError, ReadFileProgress}; use std::fs::File; @@ -26,7 +26,7 @@ impl UIProvider for TestProvider { #[test] fn test_filemanager() { - let chan: IpcSender = FileManagerThreadFactory::new(TEST_PROVIDER); + let filemanager = FileManager::new(TEST_PROVIDER); // Try to open a dummy file "tests/unit/net/test.jpeg" in tree let mut handler = File::open("test.jpeg").expect("test.jpeg is stolen"); @@ -41,7 +41,7 @@ fn test_filemanager() { { // Try to select a dummy file "tests/unit/net/test.jpeg" let (tx, rx) = ipc::channel().unwrap(); - chan.send(FileManagerThreadMsg::SelectFile(patterns.clone(), tx, origin.clone(), None)).unwrap(); + filemanager.handle(FileManagerThreadMsg::SelectFile(patterns.clone(), tx, origin.clone(), None), None); let selected = rx.recv().expect("Broken channel") .expect("The file manager failed to find test.jpeg"); @@ -52,7 +52,7 @@ fn test_filemanager() { // Test by reading, expecting same content { let (tx2, rx2) = ipc::channel().unwrap(); - chan.send(FileManagerThreadMsg::ReadFile(tx2, selected.id.clone(), false, origin.clone())).unwrap(); + filemanager.handle(FileManagerThreadMsg::ReadFile(tx2, selected.id.clone(), false, origin.clone()), None); let msg = rx2.recv().expect("Broken channel"); @@ -82,7 +82,7 @@ fn test_filemanager() { // Delete the id { let (tx2, rx2) = ipc::channel().unwrap(); - chan.send(FileManagerThreadMsg::DecRef(selected.id.clone(), origin.clone(), tx2)).unwrap(); + filemanager.handle(FileManagerThreadMsg::DecRef(selected.id.clone(), origin.clone(), tx2), None); let ret = rx2.recv().expect("Broken channel"); assert!(ret.is_ok(), "DecRef is not okay"); @@ -91,7 +91,7 @@ fn test_filemanager() { // Test by reading again, expecting read error because we invalidated the id { let (tx2, rx2) = ipc::channel().unwrap(); - chan.send(FileManagerThreadMsg::ReadFile(tx2, selected.id.clone(), false, origin.clone())).unwrap(); + filemanager.handle(FileManagerThreadMsg::ReadFile(tx2, selected.id.clone(), false, origin.clone()), None); let msg = rx2.recv().expect("Broken channel"); @@ -103,13 +103,4 @@ fn test_filemanager() { } } } - - let _ = chan.send(FileManagerThreadMsg::Exit); - - { - let (tx, rx) = ipc::channel().unwrap(); - let _ = chan.send(FileManagerThreadMsg::SelectFile(patterns.clone(), tx, origin.clone(), None)); - - assert!(rx.try_recv().is_err(), "The thread should not respond normally after exited"); - } } diff --git a/tests/unit/net/resource_thread.rs b/tests/unit/net/resource_thread.rs index 1079677c0a8f..b6da4f4f5249 100644 --- a/tests/unit/net/resource_thread.rs +++ b/tests/unit/net/resource_thread.rs @@ -4,7 +4,6 @@ use ipc_channel::ipc; use msg::constellation_msg::{PipelineId, ReferrerPolicy}; -use net::filemanager_thread::{FileManagerThreadFactory, TFDProvider}; use net::resource_thread::new_core_resource_thread; use net_traits::hosts::{parse_hostsfile, host_replacement}; use net_traits::{CoreResourceMsg, LoadData, LoadConsumer, LoadContext}; @@ -16,8 +15,6 @@ use std::net::IpAddr; use std::sync::mpsc::channel; use url::Url; -const TFD_PROVIDER: &'static TFDProvider = &TFDProvider; - fn ip(s: &str) -> IpAddr { s.parse().unwrap() } @@ -40,9 +37,8 @@ impl LoadOrigin for ResourceTest { fn test_exit() { let (tx, _rx) = ipc::channel().unwrap(); let (sender, receiver) = ipc::channel().unwrap(); - let filemanager_chan = FileManagerThreadFactory::new(TFD_PROVIDER); let (resource_thread, _) = new_core_resource_thread( - "".to_owned(), None, ProfilerChan(tx), filemanager_chan, None); + "".to_owned(), None, ProfilerChan(tx), None); resource_thread.send(CoreResourceMsg::Exit(sender)).unwrap(); receiver.recv().unwrap(); } @@ -51,9 +47,8 @@ fn test_exit() { fn test_bad_scheme() { let (tx, _rx) = ipc::channel().unwrap(); let (sender, receiver) = ipc::channel().unwrap(); - let filemanager_chan = FileManagerThreadFactory::new(TFD_PROVIDER); let (resource_thread, _) = new_core_resource_thread( - "".to_owned(), None, ProfilerChan(tx), filemanager_chan, None); + "".to_owned(), None, ProfilerChan(tx), None); let (start_chan, start) = ipc::channel().unwrap(); let url = Url::parse("bogus://whatever").unwrap(); resource_thread.send(CoreResourceMsg::Load(LoadData::new(LoadContext::Browsing, url, &ResourceTest), @@ -232,9 +227,8 @@ fn test_cancelled_listener() { let (tx, _rx) = ipc::channel().unwrap(); let (exit_sender, exit_receiver) = ipc::channel().unwrap(); - let filemanager_chan = FileManagerThreadFactory::new(TFD_PROVIDER); let (resource_thread, _) = new_core_resource_thread( - "".to_owned(), None, ProfilerChan(tx), filemanager_chan, None); + "".to_owned(), None, ProfilerChan(tx), None); let (sender, receiver) = ipc::channel().unwrap(); let (id_sender, id_receiver) = ipc::channel().unwrap(); let (sync_sender, sync_receiver) = ipc::channel().unwrap();