remove unnecessary thread in filereader, add stream TODO

This commit is contained in:
Gregory Terzian 2019-12-10 14:19:49 +08:00
parent 7aa68c8fe7
commit ed88a67cca
2 changed files with 26 additions and 46 deletions

View file

@ -23,8 +23,7 @@ use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
use crate::dom::progressevent::ProgressEvent; use crate::dom::progressevent::ProgressEvent;
use crate::script_runtime::JSContext; use crate::script_runtime::JSContext;
use crate::task::TaskCanceller; use crate::task_source::file_reading::FileReadingTask;
use crate::task_source::file_reading::{FileReadingTask, FileReadingTaskSource};
use crate::task_source::{TaskSource, TaskSourceName}; use crate::task_source::{TaskSource, TaskSourceName};
use base64; use base64;
use dom_struct::dom_struct; use dom_struct::dom_struct;
@ -37,8 +36,6 @@ use mime::{self, Mime};
use servo_atoms::Atom; use servo_atoms::Atom;
use std::cell::Cell; use std::cell::Cell;
use std::ptr; use std::ptr;
use std::sync::Arc;
use std::thread;
#[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)] #[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)]
pub enum FileReaderFunction { pub enum FileReaderFunction {
@ -236,7 +233,7 @@ impl FileReader {
filereader: TrustedFileReader, filereader: TrustedFileReader,
gen_id: GenerationId, gen_id: GenerationId,
data: ReadMetaData, data: ReadMetaData,
blob_contents: Arc<Vec<u8>>, blob_contents: Vec<u8>,
) { ) {
let fr = filereader.root(); let fr = filereader.root();
@ -426,6 +423,7 @@ impl FileReader {
self.generation_id.set(GenerationId(prev_id + 1)); self.generation_id.set(GenerationId(prev_id + 1));
} }
/// <https://w3c.github.io/FileAPI/#readOperation>
fn read( fn read(
&self, &self,
function: FileReaderFunction, function: FileReaderFunction,
@ -443,35 +441,40 @@ impl FileReader {
// Step 3 // Step 3
*self.result.borrow_mut() = None; *self.result.borrow_mut() = None;
let blob_contents = Arc::new(blob.get_bytes().unwrap_or(vec![]));
let type_ = blob.Type(); let type_ = blob.Type();
let load_data = ReadMetaData::new(String::from(type_), label.map(String::from), function); let load_data = ReadMetaData::new(String::from(type_), label.map(String::from), function);
let fr = Trusted::new(self);
let GenerationId(prev_id) = self.generation_id.get(); let GenerationId(prev_id) = self.generation_id.get();
self.generation_id.set(GenerationId(prev_id + 1)); self.generation_id.set(GenerationId(prev_id + 1));
let gen_id = self.generation_id.get(); let gen_id = self.generation_id.get();
// Step 10, in parallel, wait on stream promises to resolve and queue tasks.
// TODO: follow the spec which requires implementing blob `get_stream`,
// see https://github.com/servo/servo/issues/25209
// Currently bytes are first read "sync", and then the appropriate tasks are queued.
// Read the blob bytes "sync".
let blob_contents = blob.get_bytes().unwrap_or_else(|_| vec![]);
let filereader = Trusted::new(self);
let global = self.global(); let global = self.global();
let canceller = global.task_canceller(TaskSourceName::FileReading); let canceller = global.task_canceller(TaskSourceName::FileReading);
let task_source = global.file_reading_task_source(); let task_source = global.file_reading_task_source();
thread::Builder::new() // Queue tasks as appropriate.
.name("file reader async operation".to_owned()) let task = FileReadingTask::ProcessRead(filereader.clone(), gen_id);
.spawn(move || { task_source.queue_with_canceller(task, &canceller).unwrap();
perform_annotated_read_operation(
gen_id, if !blob_contents.is_empty() {
load_data, let task = FileReadingTask::ProcessReadData(filereader.clone(), gen_id);
blob_contents, task_source.queue_with_canceller(task, &canceller).unwrap();
fr, }
task_source,
canceller, let task = FileReadingTask::ProcessReadEOF(filereader, gen_id, load_data, blob_contents);
) task_source.queue_with_canceller(task, &canceller).unwrap();
})
.expect("Thread spawning failed");
Ok(()) Ok(())
} }
@ -480,25 +483,3 @@ impl FileReader {
self.ready_state.set(state); self.ready_state.set(state);
} }
} }
// https://w3c.github.io/FileAPI/#thread-read-operation
fn perform_annotated_read_operation(
gen_id: GenerationId,
data: ReadMetaData,
blob_contents: Arc<Vec<u8>>,
filereader: TrustedFileReader,
task_source: FileReadingTaskSource,
canceller: TaskCanceller,
) {
// Step 4
let task = FileReadingTask::ProcessRead(filereader.clone(), gen_id);
task_source.queue_with_canceller(task, &canceller).unwrap();
if !blob_contents.is_empty() {
let task = FileReadingTask::ProcessReadData(filereader.clone(), gen_id);
task_source.queue_with_canceller(task, &canceller).unwrap();
}
let task = FileReadingTask::ProcessReadEOF(filereader, gen_id, data, blob_contents);
task_source.queue_with_canceller(task, &canceller).unwrap();
}

View file

@ -8,7 +8,6 @@ use crate::script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCatego
use crate::task::{TaskCanceller, TaskOnce}; use crate::task::{TaskCanceller, TaskOnce};
use crate::task_source::{TaskSource, TaskSourceName}; use crate::task_source::{TaskSource, TaskSourceName};
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;
use std::sync::Arc;
#[derive(JSTraceable)] #[derive(JSTraceable)]
pub struct FileReadingTaskSource(pub Box<dyn ScriptChan + Send + 'static>, pub PipelineId); pub struct FileReadingTaskSource(pub Box<dyn ScriptChan + Send + 'static>, pub PipelineId);
@ -46,7 +45,7 @@ pub enum FileReadingTask {
ProcessRead(TrustedFileReader, GenerationId), ProcessRead(TrustedFileReader, GenerationId),
ProcessReadData(TrustedFileReader, GenerationId), ProcessReadData(TrustedFileReader, GenerationId),
ProcessReadError(TrustedFileReader, GenerationId, DOMErrorName), ProcessReadError(TrustedFileReader, GenerationId, DOMErrorName),
ProcessReadEOF(TrustedFileReader, GenerationId, ReadMetaData, Arc<Vec<u8>>), ProcessReadEOF(TrustedFileReader, GenerationId, ReadMetaData, Vec<u8>),
} }
impl FileReadingTask { impl FileReadingTask {