Make first argument of DOMManipulationTaskSource as a Box<ScriptChan +

Send>

We don't have `window` for `workers`. So, if we use `global.as_window()`
to get the DOMManipulationTaskSource, it will make worker panic.
Instead, we should get the DOMManipulationTaskSource from each own
thread.

Ref: https://github.com/servo/servo/pull/20755#discussion_r193557746
This commit is contained in:
CYBAI 2018-06-10 21:02:11 +08:00
parent 924a78c6c6
commit 42903412c7
5 changed files with 32 additions and 11 deletions

View file

@ -56,6 +56,7 @@ use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use task::TaskCanceller; use task::TaskCanceller;
use task_source::TaskSourceName; use task_source::TaskSourceName;
use task_source::dom_manipulation::DOMManipulationTaskSource;
use task_source::file_reading::FileReadingTaskSource; use task_source::file_reading::FileReadingTaskSource;
use task_source::networking::NetworkingTaskSource; use task_source::networking::NetworkingTaskSource;
use task_source::performance_timeline::PerformanceTimelineTaskSource; use task_source::performance_timeline::PerformanceTimelineTaskSource;
@ -680,6 +681,16 @@ impl GlobalScope {
unreachable!(); unreachable!();
} }
pub fn dom_manipulation_task_source(&self) -> DOMManipulationTaskSource {
if let Some(window) = self.downcast::<Window>() {
return window.dom_manipulation_task_source();
}
if let Some(worker) = self.downcast::<WorkerGlobalScope>() {
return worker.dom_manipulation_task_source();
}
unreachable!();
}
/// Channel to send messages to the file reading task source of /// Channel to send messages to the file reading task source of
/// this of this global scope. /// this of this global scope.
pub fn file_reading_task_source(&self) -> FileReadingTaskSource { pub fn file_reading_task_source(&self) -> FileReadingTaskSource {

View file

@ -43,6 +43,7 @@ use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use task::TaskCanceller; use task::TaskCanceller;
use task_source::dom_manipulation::DOMManipulationTaskSource;
use task_source::file_reading::FileReadingTaskSource; use task_source::file_reading::FileReadingTaskSource;
use task_source::networking::NetworkingTaskSource; use task_source::networking::NetworkingTaskSource;
use task_source::performance_timeline::PerformanceTimelineTaskSource; use task_source::performance_timeline::PerformanceTimelineTaskSource;
@ -419,6 +420,10 @@ impl WorkerGlobalScope {
} }
} }
pub fn dom_manipulation_task_source(&self) -> DOMManipulationTaskSource {
DOMManipulationTaskSource(self.script_chan(), self.pipeline_id())
}
pub fn file_reading_task_source(&self) -> FileReadingTaskSource { pub fn file_reading_task_source(&self) -> FileReadingTaskSource {
FileReadingTaskSource(self.script_chan(), self.pipeline_id()) FileReadingTaskSource(self.script_chan(), self.pipeline_id())
} }

View file

@ -217,7 +217,7 @@ pub fn notify_about_rejected_promises(global: &GlobalScope) {
let target = Trusted::new(global.upcast::<EventTarget>()); let target = Trusted::new(global.upcast::<EventTarget>());
// Step 4. // Step 4.
global.as_window().dom_manipulation_task_source().queue( global.dom_manipulation_task_source().queue(
task!(unhandled_rejection_event: move || { task!(unhandled_rejection_event: move || {
let target = target.root(); let target = target.root();
let cx = target.global().get_cx(); let cx = target.global().get_cx();

View file

@ -501,7 +501,7 @@ pub struct ScriptThread {
/// events in the event queue. /// events in the event queue.
chan: MainThreadScriptChan, chan: MainThreadScriptChan,
dom_manipulation_task_sender: Sender<MainThreadScriptMsg>, dom_manipulation_task_sender: Box<ScriptChan>,
media_element_task_sender: Sender<MainThreadScriptMsg>, media_element_task_sender: Sender<MainThreadScriptMsg>,
@ -1020,7 +1020,7 @@ impl ScriptThread {
task_queue, task_queue,
chan: MainThreadScriptChan(chan.clone()), chan: MainThreadScriptChan(chan.clone()),
dom_manipulation_task_sender: chan.clone(), dom_manipulation_task_sender: boxed_script_sender.clone(),
media_element_task_sender: chan.clone(), media_element_task_sender: chan.clone(),
user_interaction_task_sender: chan.clone(), user_interaction_task_sender: chan.clone(),
networking_task_sender: boxed_script_sender.clone(), networking_task_sender: boxed_script_sender.clone(),

View file

@ -8,17 +8,21 @@ use dom::event::{EventBubbles, EventCancelable, EventTask, SimpleEventTask};
use dom::eventtarget::EventTarget; use dom::eventtarget::EventTarget;
use dom::window::Window; use dom::window::Window;
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;
use script_runtime::{CommonScriptMsg, ScriptThreadEventCategory}; use script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCategory};
use script_thread::MainThreadScriptMsg;
use servo_atoms::Atom; use servo_atoms::Atom;
use servo_channel::Sender;
use std::fmt; use std::fmt;
use std::result::Result; use std::result::Result;
use task::{TaskCanceller, TaskOnce}; use task::{TaskCanceller, TaskOnce};
use task_source::{TaskSource, TaskSourceName}; use task_source::{TaskSource, TaskSourceName};
#[derive(Clone, JSTraceable)] #[derive(JSTraceable)]
pub struct DOMManipulationTaskSource(pub Sender<MainThreadScriptMsg>, pub PipelineId); pub struct DOMManipulationTaskSource(pub Box<ScriptChan + Send>, pub PipelineId);
impl Clone for DOMManipulationTaskSource {
fn clone(&self) -> DOMManipulationTaskSource {
DOMManipulationTaskSource(self.0.clone(), self.1.clone())
}
}
impl fmt::Debug for DOMManipulationTaskSource { impl fmt::Debug for DOMManipulationTaskSource {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@ -33,13 +37,14 @@ impl TaskSource for DOMManipulationTaskSource {
where where
T: TaskOnce + 'static, T: TaskOnce + 'static,
{ {
let msg = MainThreadScriptMsg::Common(CommonScriptMsg::Task( let msg_task = CommonScriptMsg::Task(
ScriptThreadEventCategory::ScriptEvent, ScriptThreadEventCategory::ScriptEvent,
Box::new(canceller.wrap_task(task)), Box::new(canceller.wrap_task(task)),
Some(self.1), Some(self.1),
DOMManipulationTaskSource::NAME, DOMManipulationTaskSource::NAME,
)); );
self.0.send(msg).map_err(|_| ())
self.0.send(msg_task).map_err(|_| ())
} }
} }