diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index fd471cc4d38..54a0361a69e 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -53,8 +53,9 @@ use page::Page; use profile_traits::mem; use reporter::CSSErrorReporter; use rustc_serialize::base64::{FromBase64, STANDARD, ToBase64}; -use script_task::{ScriptChan, ScriptPort, MainThreadScriptMsg, RunnableWrapper}; -use script_task::{SendableMainThreadScriptChan, MainThreadScriptChan}; +use script_task::{DOMManipulationTaskSource, UserInteractionTaskSource, NetworkingTaskSource}; +use script_task::{HistoryTraversalTaskSource, FileReadingTaskSource, SendableMainThreadScriptChan}; +use script_task::{ScriptChan, ScriptPort, MainThreadScriptChan, MainThreadScriptMsg, RunnableWrapper}; use script_traits::ScriptMsg as ConstellationMsg; use script_traits::{MsDuration, TimerEvent, TimerEventId, TimerEventRequest, TimerSource}; use selectors::parser::PseudoElement; @@ -114,6 +115,16 @@ pub struct Window { eventtarget: EventTarget, #[ignore_heap_size_of = "trait objects are hard"] 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>, crypto: MutNullableHeap>, navigator: MutNullableHeap>, @@ -238,28 +249,23 @@ impl Window { } pub fn dom_manipulation_task_source(&self) -> Box { - // FIXME: Use a different channel instead of the generic script_chan - self.script_chan.clone() + self.dom_manipulation_task_source.clone() } pub fn user_interaction_task_source(&self) -> Box { - // FIXME: Use a different channel instead of the generic script_chan - self.script_chan.clone() + self.user_interaction_task_source.clone() } pub fn networking_task_source(&self) -> Box { - // FIXME: Use a different channel instead of the generic script_chan - self.script_chan.clone() + self.networking_task_source.clone() } pub fn history_traversal_task_source(&self) -> Box { - // FIXME: Use a different channel instead of the generic script_chan - self.script_chan.clone() + self.history_traversal_task_source.clone() } pub fn file_reading_task_source(&self) -> Box { - // FIXME: Use a different channel instead of the generic script_chan - self.script_chan.clone() + self.file_reading_task_source.clone() } pub fn main_thread_script_chan(&self) -> &Sender { @@ -1251,6 +1257,11 @@ impl Window { pub fn new(runtime: Rc, page: Rc, 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, compositor: IpcSender, image_cache_task: ImageCacheTask, @@ -1276,6 +1287,11 @@ impl Window { let win = box Window { eventtarget: EventTarget::new_inherited(), 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, console: Default::default(), crypto: Default::default(), diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 1dcf707a735..b42b74573a8 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -352,6 +352,102 @@ impl MainThreadScriptChan { } } +// FIXME: Use a task source specific message instead of MainThreadScriptMsg +#[derive(JSTraceable)] +pub struct DOMManipulationTaskSource(pub Sender); + +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 { + 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); + +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 { + 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); + +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 { + 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); + +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 { + 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); + +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 { + 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); + +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 { + let ProfilerTaskSource(ref chan) = *self; + box ProfilerTaskSource((*chan).clone()) + } +} + pub struct StackRootTLS<'a>(PhantomData<&'a u32>); 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 /// events in the event queue. 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. control_chan: IpcSender, @@ -504,7 +609,7 @@ impl ScriptTaskFactory for ScriptTask { PipelineNamespace::install(state.pipeline_namespace_id); let roots = RootCollection::new(); 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 id = state.id; let parent_info = state.parent_info; @@ -512,7 +617,7 @@ impl ScriptTaskFactory for ScriptTask { let window_size = state.window_size; let script_task = ScriptTask::new(state, script_port, - chan); + script_chan); SCRIPT_TASK_ROOT.with(|root| { *root.borrow_mut() = Some(&script_task as *const _); @@ -620,7 +725,7 @@ impl ScriptTask { /// Creates a new script task. pub fn new(state: InitialScriptState, port: Receiver, - chan: MainThreadScriptChan) + chan: Sender) -> ScriptTask { let runtime = ScriptTask::new_rt_and_cx(); @@ -655,7 +760,13 @@ impl ScriptTask { storage_task: state.storage_task, 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_port: control_port, constellation_chan: state.constellation_chan, @@ -1630,6 +1741,11 @@ impl ScriptTask { }; let mut page_remover = AutoPageRemover::new(self, page_to_remove); 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(); 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(), page.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.compositor.borrow_mut().clone(), self.image_cache_task.clone(),