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