Skip to content

Commit

Permalink
introduce "per task source" ignoring of tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
gterzian committed Jul 10, 2018
1 parent ce43056 commit 671627e
Show file tree
Hide file tree
Showing 21 changed files with 127 additions and 34 deletions.
21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions components/script/Cargo.toml
Expand Up @@ -44,6 +44,7 @@ dom_struct = {path = "../dom_struct"}
domobject_derive = {path = "../domobject_derive"}
embedder_traits = {path = "../embedder_traits"}
encoding_rs = "0.7"
enum-iterator = "0.2.0"
euclid = "0.17"
fnv = "1.0"
gleam = "0.5"
Expand Down
6 changes: 4 additions & 2 deletions components/script/dom/eventsource.rs
Expand Up @@ -34,7 +34,7 @@ use std::cell::Cell;
use std::mem;
use std::str::{Chars, FromStr};
use std::sync::{Arc, Mutex};
use task_source::TaskSource;
use task_source::{TaskSource, TaskSourceName};
use timers::OneshotTimerCallback;
use utf8;

Expand Down Expand Up @@ -482,10 +482,12 @@ impl EventSource {
data: String::new(),
last_event_id: String::new(),
};
// TODO: use the "remote event task source", and canceller.
// https://html.spec.whatwg.org/multipage/#remote-event-task-source
let listener = NetworkListener {
context: Arc::new(Mutex::new(context)),
task_source: global.networking_task_source(),
canceller: Some(global.task_canceller())
canceller: Some(global.task_canceller(TaskSourceName::Networking))
};
ROUTER.add_route(action_receiver.to_opaque(), Box::new(move |message| {
listener.notify_fetch(message.to().unwrap());
Expand Down
4 changes: 2 additions & 2 deletions components/script/dom/filereader.rs
Expand Up @@ -35,7 +35,7 @@ use std::ptr;
use std::sync::Arc;
use std::thread;
use task::TaskCanceller;
use task_source::TaskSource;
use task_source::{TaskSource, TaskSourceName};
use task_source::file_reading::{FileReadingTask, FileReadingTaskSource};

#[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)]
Expand Down Expand Up @@ -452,7 +452,7 @@ impl FileReader {
let gen_id = self.generation_id.get();

let global = self.global();
let canceller = global.task_canceller();
let canceller = global.task_canceller(TaskSourceName::FileReading);
let task_source = global.file_reading_task_source();

thread::Builder::new()
Expand Down
8 changes: 6 additions & 2 deletions components/script/dom/globalscope.rs
Expand Up @@ -52,6 +52,7 @@ use std::rc::Rc;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use task::TaskCanceller;
use task_source::TaskSourceName;
use task_source::file_reading::FileReadingTaskSource;
use task_source::networking::NetworkingTaskSource;
use task_source::performance_timeline::PerformanceTimelineTaskSource;
Expand Down Expand Up @@ -508,11 +509,14 @@ impl GlobalScope {

/// Returns the task canceller of this global to ensure that everything is
/// properly cancelled when the global scope is destroyed.
pub fn task_canceller(&self) -> TaskCanceller {
pub fn task_canceller(&self, name: TaskSourceName) -> TaskCanceller {
if let Some(window) = self.downcast::<Window>() {
return window.task_canceller();
return window.task_canceller(name);
}
if let Some(worker) = self.downcast::<WorkerGlobalScope>() {
// Note: the "name" is not passed to the worker,
// because 'closing' it only requires one task canceller for all task sources.
// https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-closing
return worker.task_canceller();
}
unreachable!();
Expand Down
6 changes: 3 additions & 3 deletions components/script/dom/htmlimageelement.rs
Expand Up @@ -58,7 +58,7 @@ use std::i32;
use std::sync::{Arc, Mutex};
use style::attr::{AttrValue, LengthOrPercentageOrAuto, parse_double, parse_unsigned_integer};
use style::str::is_ascii_digit;
use task_source::TaskSource;
use task_source::{TaskSource, TaskSourceName};

enum ParseState {
InDescriptor,
Expand Down Expand Up @@ -185,7 +185,7 @@ impl HTMLImageElement {

let window = window_from_node(elem);
let task_source = window.networking_task_source();
let task_canceller = window.task_canceller();
let task_canceller = window.task_canceller(TaskSourceName::Networking);
let generation = elem.generation.get();
ROUTER.add_route(responder_receiver.to_opaque(), Box::new(move |message| {
debug!("Got image {:?}", message);
Expand Down Expand Up @@ -253,7 +253,7 @@ impl HTMLImageElement {
let listener = NetworkListener {
context: context,
task_source: window.networking_task_source(),
canceller: Some(window.task_canceller()),
canceller: Some(window.task_canceller(TaskSourceName::Networking)),
};
ROUTER.add_route(action_receiver.to_opaque(), Box::new(move |message| {
listener.notify_fetch(message.to().unwrap());
Expand Down
4 changes: 2 additions & 2 deletions components/script/dom/htmlmediaelement.rs
Expand Up @@ -46,7 +46,7 @@ use std::collections::VecDeque;
use std::mem;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use task_source::TaskSource;
use task_source::{TaskSource, TaskSourceName};
use time::{self, Timespec, Duration};

#[dom_struct]
Expand Down Expand Up @@ -608,7 +608,7 @@ impl HTMLMediaElement {
let listener = NetworkListener {
context: context,
task_source: window.networking_task_source(),
canceller: Some(window.task_canceller())
canceller: Some(window.task_canceller(TaskSourceName::Networking))
};
ROUTER.add_route(action_receiver.to_opaque(), Box::new(move |message| {
listener.notify_fetch(message.to().unwrap());
Expand Down
3 changes: 2 additions & 1 deletion components/script/dom/htmlscriptelement.rs
Expand Up @@ -41,6 +41,7 @@ use std::path::PathBuf;
use std::process::{Command, Stdio};
use std::sync::{Arc, Mutex};
use style::str::{HTML_SPACE_CHARACTERS, StaticStringVec};
use task_source::TaskSourceName;
use uuid::Uuid;

#[dom_struct]
Expand Down Expand Up @@ -273,7 +274,7 @@ fn fetch_a_classic_script(script: &HTMLScriptElement,
let listener = NetworkListener {
context: context,
task_source: doc.window().networking_task_source(),
canceller: Some(doc.window().task_canceller())
canceller: Some(doc.window().task_canceller(TaskSourceName::Networking))
};

ROUTER.add_route(action_receiver.to_opaque(), Box::new(move |message| {
Expand Down
14 changes: 11 additions & 3 deletions components/script/dom/websocket.rs
Expand Up @@ -39,7 +39,7 @@ use std::cell::Cell;
use std::ptr;
use std::thread;
use task::{TaskOnce, TaskCanceller};
use task_source::TaskSource;
use task_source::{TaskSource, TaskSourceName};
use task_source::networking::NetworkingTaskSource;

#[derive(Clone, Copy, Debug, JSTraceable, MallocSizeOf, PartialEq)]
Expand Down Expand Up @@ -199,8 +199,11 @@ impl WebSocket {
};
let _ = global.core_resource_thread().send(CoreResourceMsg::Fetch(request, channels));

// TODO: use a dedicated task source,
// https://html.spec.whatwg.org/multipage/#websocket-task-source
// When making the switch, also update the task_canceller call.
let task_source = global.networking_task_source();
let canceller = global.task_canceller();
let canceller = global.task_canceller(TaskSourceName::Networking);
thread::spawn(move || {
while let Ok(event) = dom_event_receiver.recv() {
match event {
Expand Down Expand Up @@ -391,8 +394,13 @@ impl WebSocketMethods for WebSocket {
self.ready_state.set(WebSocketRequestState::Closing);

let address = Trusted::new(self);
// TODO: use a dedicated task source,
// https://html.spec.whatwg.org/multipage/#websocket-task-source
// When making the switch, also update the task_canceller call.
let task_source = self.global().networking_task_source();
fail_the_websocket_connection(address, &task_source, &self.global().task_canceller());
fail_the_websocket_connection(address,
&task_source,
&self.global().task_canceller(TaskSourceName::Networking));
}
WebSocketRequestState::Open => {
self.ready_state.set(WebSocketRequestState::Closing);
Expand Down
34 changes: 25 additions & 9 deletions components/script/dom/window.rs
Expand Up @@ -109,6 +109,7 @@ use style::str::HTML_SPACE_CHARACTERS;
use style::stylesheets::CssRuleType;
use style_traits::{CSSPixel, DevicePixel, ParsingMode};
use task::TaskCanceller;
use task_source::TaskSourceName;
use task_source::dom_manipulation::DOMManipulationTaskSource;
use task_source::file_reading::FileReadingTaskSource;
use task_source::history_traversal::HistoryTraversalTaskSource;
Expand Down Expand Up @@ -246,9 +247,9 @@ pub struct Window {

current_viewport: Cell<Rect<Au>>,

/// A flag to prevent async events from attempting to interact with this window.
/// A map of flags to prevent events from a given task source from attempting to interact with this window.
#[ignore_malloc_size_of = "defined in std"]
ignore_further_async_events: DomRefCell<Arc<AtomicBool>>,
ignore_further_async_events: DomRefCell<HashMap<TaskSourceName, Arc<AtomicBool>>>,

error_reporter: CSSErrorReporter,

Expand Down Expand Up @@ -308,7 +309,15 @@ impl Window {
*self.js_runtime.borrow_for_script_deallocation() = None;
self.window_proxy.set(None);
self.current_state.set(WindowState::Zombie);
self.ignore_further_async_events.borrow().store(true, Ordering::Relaxed);
self.ignore_all_events();
}
}

fn ignore_all_events(&self) {
let mut ignore_flags = self.ignore_further_async_events.borrow_mut();
for task_source_name in TaskSourceName::all() {
let flag = ignore_flags.entry(task_source_name).or_insert(Default::default());
flag.store(true, Ordering::Relaxed);
}
}

Expand Down Expand Up @@ -1065,9 +1074,11 @@ impl Window {
self.paint_worklet.or_init(|| self.new_paint_worklet())
}

pub fn task_canceller(&self) -> TaskCanceller {
pub fn task_canceller(&self, name: TaskSourceName) -> TaskCanceller {
let mut flags = self.ignore_further_async_events.borrow_mut();
let cancel_flag = flags.entry(name).or_insert(Default::default());
TaskCanceller {
cancelled: Some(self.ignore_further_async_events.borrow().clone()),
cancelled: Some(cancel_flag.clone()),
}
}

Expand All @@ -1084,8 +1095,12 @@ impl Window {
/// This sets the current `ignore_further_async_events` sentinel value to
/// `true` and replaces it with a brand new one for future tasks.
pub fn cancel_all_tasks(&self) {
let cancelled = mem::replace(&mut *self.ignore_further_async_events.borrow_mut(), Default::default());
cancelled.store(true, Ordering::Relaxed);
let mut ignore_flags = self.ignore_further_async_events.borrow_mut();
for task_source_name in TaskSourceName::all() {
let mut flag = ignore_flags.entry(task_source_name).or_insert(Default::default());
let cancelled = mem::replace(&mut *flag, Default::default());
cancelled.store(true, Ordering::Relaxed);
}
}

pub fn clear_js_runtime(&self) {
Expand Down Expand Up @@ -1117,7 +1132,7 @@ impl Window {
self.current_state.set(WindowState::Zombie);
*self.js_runtime.borrow_mut() = None;
self.window_proxy.set(None);
self.ignore_further_async_events.borrow().store(true, Ordering::SeqCst);
self.ignore_all_events();
}

/// <https://drafts.csswg.org/cssom-view/#dom-window-scroll>
Expand Down Expand Up @@ -1998,9 +2013,10 @@ impl Window {
});
// FIXME(nox): Why are errors silenced here?
// TODO(#12718): Use the "posted message task source".
// TODO: When switching to the right task source, update the task_canceller call too.
let _ = self.script_chan.send(CommonScriptMsg::Task(
ScriptThreadEventCategory::DomEvent,
Box::new(self.task_canceller().wrap_task(task)),
Box::new(self.task_canceller(TaskSourceName::DOMManipulation).wrap_task(task)),
self.pipeline_id()
));
}
Expand Down
3 changes: 2 additions & 1 deletion components/script/dom/xmlhttprequest.rs
Expand Up @@ -70,6 +70,7 @@ use std::ptr::NonNull;
use std::slice;
use std::str;
use std::sync::{Arc, Mutex};
use task_source::TaskSourceName;
use task_source::networking::NetworkingTaskSource;
use time;
use timers::{OneshotTimerCallback, OneshotTimerHandle};
Expand Down Expand Up @@ -268,7 +269,7 @@ impl XMLHttpRequest {
let listener = NetworkListener {
context: context,
task_source: task_source,
canceller: Some(global.task_canceller())
canceller: Some(global.task_canceller(TaskSourceName::Networking))
};
ROUTER.add_route(action_receiver.to_opaque(), Box::new(move |message| {
listener.notify_fetch(message.to().unwrap());
Expand Down
3 changes: 2 additions & 1 deletion components/script/fetch.rs
Expand Up @@ -31,6 +31,7 @@ use servo_url::ServoUrl;
use std::mem;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use task_source::TaskSourceName;

struct FetchContext {
fetch_promise: Option<TrustedPromise>,
Expand Down Expand Up @@ -154,7 +155,7 @@ pub fn Fetch(global: &GlobalScope, input: RequestInfo, init: RootedTraceableBox<
let listener = NetworkListener {
context: fetch_context,
task_source: global.networking_task_source(),
canceller: Some(global.task_canceller())
canceller: Some(global.task_canceller(TaskSourceName::Networking))
};

ROUTER.add_route(action_receiver.to_opaque(), Box::new(move |message| {
Expand Down
3 changes: 2 additions & 1 deletion components/script/layout_image.rs
Expand Up @@ -17,6 +17,7 @@ use net_traits::request::{Destination, RequestInit as FetchRequestInit};
use network_listener::{NetworkListener, PreInvoke};
use servo_url::ServoUrl;
use std::sync::{Arc, Mutex};
use task_source::TaskSourceName;

struct LayoutImageContext {
id: PendingImageId,
Expand Down Expand Up @@ -62,7 +63,7 @@ pub fn fetch_image_for_layout(url: ServoUrl,
let listener = NetworkListener {
context: context,
task_source: window.networking_task_source(),
canceller: Some(window.task_canceller()),
canceller: Some(window.task_canceller(TaskSourceName::Networking)),
};
ROUTER.add_route(action_receiver.to_opaque(), Box::new(move |message| {
listener.notify_fetch(message.to().unwrap());
Expand Down
1 change: 1 addition & 0 deletions components/script/lib.rs
Expand Up @@ -37,6 +37,7 @@ extern crate dom_struct;
extern crate domobject_derive;
extern crate embedder_traits;
extern crate encoding_rs;
#[macro_use] extern crate enum_iterator;
extern crate euclid;
extern crate fnv;
extern crate gleam;
Expand Down
3 changes: 2 additions & 1 deletion components/script/stylesheet_loader.rs
Expand Up @@ -35,6 +35,7 @@ use style::stylesheets::{CssRules, ImportRule, Namespaces, Stylesheet, Styleshee
use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
use style::stylesheets::import_rule::ImportSheet;
use style::values::CssUrl;
use task_source::TaskSourceName;

pub trait StylesheetOwner {
/// Returns whether this element was inserted by the parser (i.e., it should
Expand Down Expand Up @@ -228,7 +229,7 @@ impl<'a> StylesheetLoader<'a> {
let listener = NetworkListener {
context: context,
task_source: document.window().networking_task_source(),
canceller: Some(document.window().task_canceller())
canceller: Some(document.window().task_canceller(TaskSourceName::Networking))
};
ROUTER.add_route(action_receiver.to_opaque(), Box::new(move |message| {
listener.notify_fetch(message.to().unwrap());
Expand Down
4 changes: 3 additions & 1 deletion components/script/task_source/dom_manipulation.rs
Expand Up @@ -15,7 +15,7 @@ use std::fmt;
use std::result::Result;
use std::sync::mpsc::Sender;
use task::{TaskCanceller, TaskOnce};
use task_source::TaskSource;
use task_source::{TaskSource, TaskSourceName};

#[derive(Clone, JSTraceable)]
pub struct DOMManipulationTaskSource(pub Sender<MainThreadScriptMsg>, pub PipelineId);
Expand All @@ -27,6 +27,8 @@ impl fmt::Debug for DOMManipulationTaskSource {
}

impl TaskSource for DOMManipulationTaskSource {
const NAME: TaskSourceName = TaskSourceName::DOMManipulation;

fn queue_with_canceller<T>(
&self,
task: T,
Expand Down

0 comments on commit 671627e

Please sign in to comment.