Split script_chan into 5 different task queue channels

This commit is contained in:
Keith Yeung 2015-12-06 23:07:56 -08:00
parent 7438bc0425
commit f478194736
2 changed files with 153 additions and 16 deletions

View file

@ -53,8 +53,9 @@ use page::Page;
use profile_traits::mem; use profile_traits::mem;
use reporter::CSSErrorReporter; use reporter::CSSErrorReporter;
use rustc_serialize::base64::{FromBase64, STANDARD, ToBase64}; use rustc_serialize::base64::{FromBase64, STANDARD, ToBase64};
use script_task::{ScriptChan, ScriptPort, MainThreadScriptMsg, RunnableWrapper}; use script_task::{DOMManipulationTaskSource, UserInteractionTaskSource, NetworkingTaskSource};
use script_task::{SendableMainThreadScriptChan, MainThreadScriptChan}; use script_task::{HistoryTraversalTaskSource, FileReadingTaskSource, SendableMainThreadScriptChan};
use script_task::{ScriptChan, ScriptPort, MainThreadScriptChan, MainThreadScriptMsg, RunnableWrapper};
use script_traits::ScriptMsg as ConstellationMsg; use script_traits::ScriptMsg as ConstellationMsg;
use script_traits::{MsDuration, TimerEvent, TimerEventId, TimerEventRequest, TimerSource}; use script_traits::{MsDuration, TimerEvent, TimerEventId, TimerEventRequest, TimerSource};
use selectors::parser::PseudoElement; use selectors::parser::PseudoElement;
@ -114,6 +115,16 @@ pub struct Window {
eventtarget: EventTarget, eventtarget: EventTarget,
#[ignore_heap_size_of = "trait objects are hard"] #[ignore_heap_size_of = "trait objects are hard"]
script_chan: MainThreadScriptChan, script_chan: MainThreadScriptChan,
#[ignore_heap_size_of = "task sources are hard"]
dom_manipulation_task_source: DOMManipulationTaskSource,
#[ignore_heap_size_of = "task sources are hard"]
user_interaction_task_source: UserInteractionTaskSource,
#[ignore_heap_size_of = "task sources are hard"]
networking_task_source: NetworkingTaskSource,
#[ignore_heap_size_of = "task sources are hard"]
history_traversal_task_source: HistoryTraversalTaskSource,
#[ignore_heap_size_of = "task sources are hard"]
file_reading_task_source: FileReadingTaskSource,
console: MutNullableHeap<JS<Console>>, console: MutNullableHeap<JS<Console>>,
crypto: MutNullableHeap<JS<Crypto>>, crypto: MutNullableHeap<JS<Crypto>>,
navigator: MutNullableHeap<JS<Navigator>>, navigator: MutNullableHeap<JS<Navigator>>,
@ -238,28 +249,23 @@ impl Window {
} }
pub fn dom_manipulation_task_source(&self) -> Box<ScriptChan + Send> { pub fn dom_manipulation_task_source(&self) -> Box<ScriptChan + Send> {
// FIXME: Use a different channel instead of the generic script_chan self.dom_manipulation_task_source.clone()
self.script_chan.clone()
} }
pub fn user_interaction_task_source(&self) -> Box<ScriptChan + Send> { pub fn user_interaction_task_source(&self) -> Box<ScriptChan + Send> {
// FIXME: Use a different channel instead of the generic script_chan self.user_interaction_task_source.clone()
self.script_chan.clone()
} }
pub fn networking_task_source(&self) -> Box<ScriptChan + Send> { pub fn networking_task_source(&self) -> Box<ScriptChan + Send> {
// FIXME: Use a different channel instead of the generic script_chan self.networking_task_source.clone()
self.script_chan.clone()
} }
pub fn history_traversal_task_source(&self) -> Box<ScriptChan + Send> { pub fn history_traversal_task_source(&self) -> Box<ScriptChan + Send> {
// FIXME: Use a different channel instead of the generic script_chan self.history_traversal_task_source.clone()
self.script_chan.clone()
} }
pub fn file_reading_task_source(&self) -> Box<ScriptChan + Send> { pub fn file_reading_task_source(&self) -> Box<ScriptChan + Send> {
// FIXME: Use a different channel instead of the generic script_chan self.file_reading_task_source.clone()
self.script_chan.clone()
} }
pub fn main_thread_script_chan(&self) -> &Sender<MainThreadScriptMsg> { pub fn main_thread_script_chan(&self) -> &Sender<MainThreadScriptMsg> {
@ -1251,6 +1257,11 @@ impl Window {
pub fn new(runtime: Rc<Runtime>, pub fn new(runtime: Rc<Runtime>,
page: Rc<Page>, page: Rc<Page>,
script_chan: MainThreadScriptChan, script_chan: MainThreadScriptChan,
dom_task_source: DOMManipulationTaskSource,
user_task_source: UserInteractionTaskSource,
network_task_source: NetworkingTaskSource,
history_task_source: HistoryTraversalTaskSource,
file_task_source: FileReadingTaskSource,
image_cache_chan: ImageCacheChan, image_cache_chan: ImageCacheChan,
compositor: IpcSender<ScriptToCompositorMsg>, compositor: IpcSender<ScriptToCompositorMsg>,
image_cache_task: ImageCacheTask, image_cache_task: ImageCacheTask,
@ -1276,6 +1287,11 @@ impl Window {
let win = box Window { let win = box Window {
eventtarget: EventTarget::new_inherited(), eventtarget: EventTarget::new_inherited(),
script_chan: script_chan, script_chan: script_chan,
dom_manipulation_task_source: dom_task_source,
user_interaction_task_source: user_task_source,
networking_task_source: network_task_source,
history_traversal_task_source: history_task_source,
file_reading_task_source: file_task_source,
image_cache_chan: image_cache_chan, image_cache_chan: image_cache_chan,
console: Default::default(), console: Default::default(),
crypto: Default::default(), crypto: Default::default(),

View file

@ -352,6 +352,102 @@ impl MainThreadScriptChan {
} }
} }
// FIXME: Use a task source specific message instead of MainThreadScriptMsg
#[derive(JSTraceable)]
pub struct DOMManipulationTaskSource(pub Sender<MainThreadScriptMsg>);
impl ScriptChan for DOMManipulationTaskSource {
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
let DOMManipulationTaskSource(ref chan) = *self;
chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
}
fn clone(&self) -> Box<ScriptChan + Send> {
let DOMManipulationTaskSource(ref chan) = *self;
box DOMManipulationTaskSource((*chan).clone())
}
}
// FIXME: Use a task source specific message instead of MainThreadScriptMsg
#[derive(JSTraceable)]
pub struct UserInteractionTaskSource(pub Sender<MainThreadScriptMsg>);
impl ScriptChan for UserInteractionTaskSource {
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
let UserInteractionTaskSource(ref chan) = *self;
chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
}
fn clone(&self) -> Box<ScriptChan + Send> {
let UserInteractionTaskSource(ref chan) = *self;
box UserInteractionTaskSource((*chan).clone())
}
}
// FIXME: Use a task source specific message instead of MainThreadScriptMsg
#[derive(JSTraceable)]
pub struct NetworkingTaskSource(pub Sender<MainThreadScriptMsg>);
impl ScriptChan for NetworkingTaskSource {
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
let NetworkingTaskSource(ref chan) = *self;
chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
}
fn clone(&self) -> Box<ScriptChan + Send> {
let NetworkingTaskSource(ref chan) = *self;
box NetworkingTaskSource((*chan).clone())
}
}
// FIXME: Use a task source specific message instead of MainThreadScriptMsg
#[derive(JSTraceable)]
pub struct HistoryTraversalTaskSource(pub Sender<MainThreadScriptMsg>);
impl ScriptChan for HistoryTraversalTaskSource {
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
let HistoryTraversalTaskSource(ref chan) = *self;
chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
}
fn clone(&self) -> Box<ScriptChan + Send> {
let HistoryTraversalTaskSource(ref chan) = *self;
box HistoryTraversalTaskSource((*chan).clone())
}
}
// FIXME: Use a task source specific message instead of MainThreadScriptMsg
#[derive(JSTraceable)]
pub struct FileReadingTaskSource(pub Sender<MainThreadScriptMsg>);
impl ScriptChan for FileReadingTaskSource {
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
let FileReadingTaskSource(ref chan) = *self;
chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
}
fn clone(&self) -> Box<ScriptChan + Send> {
let FileReadingTaskSource(ref chan) = *self;
box FileReadingTaskSource((*chan).clone())
}
}
// FIXME: Use a task source specific message instead of MainThreadScriptMsg
#[derive(JSTraceable)]
pub struct ProfilerTaskSource(pub Sender<MainThreadScriptMsg>);
impl ScriptChan for ProfilerTaskSource {
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
let ProfilerTaskSource(ref chan) = *self;
chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
}
fn clone(&self) -> Box<ScriptChan + Send> {
let ProfilerTaskSource(ref chan) = *self;
box ProfilerTaskSource((*chan).clone())
}
}
pub struct StackRootTLS<'a>(PhantomData<&'a u32>); pub struct StackRootTLS<'a>(PhantomData<&'a u32>);
impl<'a> StackRootTLS<'a> { impl<'a> StackRootTLS<'a> {
@ -393,6 +489,15 @@ pub struct ScriptTask {
/// A channel to hand out to script task-based entities that need to be able to enqueue /// A channel to hand out to script task-based entities that need to be able to enqueue
/// events in the event queue. /// events in the event queue.
chan: MainThreadScriptChan, chan: MainThreadScriptChan,
dom_manipulation_task_source: DOMManipulationTaskSource,
user_interaction_task_source: UserInteractionTaskSource,
networking_task_source: NetworkingTaskSource,
history_traversal_task_source: HistoryTraversalTaskSource,
file_reading_task_source: FileReadingTaskSource,
/// A channel to hand out to tasks that need to respond to a message from the script task. /// A channel to hand out to tasks that need to respond to a message from the script task.
control_chan: IpcSender<ConstellationControlMsg>, control_chan: IpcSender<ConstellationControlMsg>,
@ -504,7 +609,7 @@ impl ScriptTaskFactory for ScriptTask {
PipelineNamespace::install(state.pipeline_namespace_id); PipelineNamespace::install(state.pipeline_namespace_id);
let roots = RootCollection::new(); let roots = RootCollection::new();
let _stack_roots_tls = StackRootTLS::new(&roots); let _stack_roots_tls = StackRootTLS::new(&roots);
let chan = MainThreadScriptChan(script_chan); let chan = MainThreadScriptChan(script_chan.clone());
let channel_for_reporter = chan.clone(); let channel_for_reporter = chan.clone();
let id = state.id; let id = state.id;
let parent_info = state.parent_info; let parent_info = state.parent_info;
@ -512,7 +617,7 @@ impl ScriptTaskFactory for ScriptTask {
let window_size = state.window_size; let window_size = state.window_size;
let script_task = ScriptTask::new(state, let script_task = ScriptTask::new(state,
script_port, script_port,
chan); script_chan);
SCRIPT_TASK_ROOT.with(|root| { SCRIPT_TASK_ROOT.with(|root| {
*root.borrow_mut() = Some(&script_task as *const _); *root.borrow_mut() = Some(&script_task as *const _);
@ -620,7 +725,7 @@ impl ScriptTask {
/// Creates a new script task. /// Creates a new script task.
pub fn new(state: InitialScriptState, pub fn new(state: InitialScriptState,
port: Receiver<MainThreadScriptMsg>, port: Receiver<MainThreadScriptMsg>,
chan: MainThreadScriptChan) chan: Sender<MainThreadScriptMsg>)
-> ScriptTask { -> ScriptTask {
let runtime = ScriptTask::new_rt_and_cx(); let runtime = ScriptTask::new_rt_and_cx();
@ -655,7 +760,13 @@ impl ScriptTask {
storage_task: state.storage_task, storage_task: state.storage_task,
port: port, port: port,
chan: chan, chan: MainThreadScriptChan(chan.clone()),
dom_manipulation_task_source: DOMManipulationTaskSource(chan.clone()),
user_interaction_task_source: UserInteractionTaskSource(chan.clone()),
networking_task_source: NetworkingTaskSource(chan.clone()),
history_traversal_task_source: HistoryTraversalTaskSource(chan.clone()),
file_reading_task_source: FileReadingTaskSource(chan),
control_chan: state.control_chan, control_chan: state.control_chan,
control_port: control_port, control_port: control_port,
constellation_chan: state.constellation_chan, constellation_chan: state.constellation_chan,
@ -1630,6 +1741,11 @@ impl ScriptTask {
}; };
let mut page_remover = AutoPageRemover::new(self, page_to_remove); let mut page_remover = AutoPageRemover::new(self, page_to_remove);
let MainThreadScriptChan(ref sender) = self.chan; let MainThreadScriptChan(ref sender) = self.chan;
let DOMManipulationTaskSource(ref dom_sender) = self.dom_manipulation_task_source;
let UserInteractionTaskSource(ref user_sender) = self.user_interaction_task_source;
let NetworkingTaskSource(ref network_sender) = self.networking_task_source;
let HistoryTraversalTaskSource(ref history_sender) = self.history_traversal_task_source;
let FileReadingTaskSource(ref file_sender) = self.file_reading_task_source;
let (ipc_timer_event_chan, ipc_timer_event_port) = ipc::channel().unwrap(); let (ipc_timer_event_chan, ipc_timer_event_port) = ipc::channel().unwrap();
ROUTER.route_ipc_receiver_to_mpsc_sender(ipc_timer_event_port, ROUTER.route_ipc_receiver_to_mpsc_sender(ipc_timer_event_port,
@ -1639,6 +1755,11 @@ impl ScriptTask {
let window = Window::new(self.js_runtime.clone(), let window = Window::new(self.js_runtime.clone(),
page.clone(), page.clone(),
MainThreadScriptChan(sender.clone()), MainThreadScriptChan(sender.clone()),
DOMManipulationTaskSource(dom_sender.clone()),
UserInteractionTaskSource(user_sender.clone()),
NetworkingTaskSource(network_sender.clone()),
HistoryTraversalTaskSource(history_sender.clone()),
FileReadingTaskSource(file_sender.clone()),
self.image_cache_channel.clone(), self.image_cache_channel.clone(),
self.compositor.borrow_mut().clone(), self.compositor.borrow_mut().clone(),
self.image_cache_task.clone(), self.image_cache_task.clone(),