mirror of
https://github.com/servo/servo.git
synced 2025-08-01 19:50:30 +01:00
Auto merge of #14260 - asajeffrey:constellation-event-loops, r=Ms2ger
Rename ScriptChan in constellation to EventLoop <!-- Please describe your changes on the following line: --> We currently have a type `ScriptChan` in the constellation, which is named after its implementation rather than its semantics. In the spec, the nearest concept seems to be event loop https://html.spec.whatwg.org/multipage/#event-loop. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes do not require tests because renaming. <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14260) <!-- Reviewable:end -->
This commit is contained in:
commit
91a2e7614c
4 changed files with 100 additions and 77 deletions
|
@ -21,6 +21,7 @@ use debugger;
|
||||||
use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg};
|
use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg};
|
||||||
use euclid::scale_factor::ScaleFactor;
|
use euclid::scale_factor::ScaleFactor;
|
||||||
use euclid::size::{Size2D, TypedSize2D};
|
use euclid::size::{Size2D, TypedSize2D};
|
||||||
|
use event_loop::EventLoop;
|
||||||
use gfx::font_cache_thread::FontCacheThread;
|
use gfx::font_cache_thread::FontCacheThread;
|
||||||
use gfx_traits::Epoch;
|
use gfx_traits::Epoch;
|
||||||
use ipc_channel::ipc::{self, IpcSender};
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
|
@ -133,10 +134,10 @@ pub struct Constellation<Message, LTF, STF> {
|
||||||
/// to receive sw manager message
|
/// to receive sw manager message
|
||||||
swmanager_receiver: Receiver<SWManagerMsg>,
|
swmanager_receiver: Receiver<SWManagerMsg>,
|
||||||
|
|
||||||
/// A map from top-level frame id and registered domain name to script channels.
|
/// A map from top-level frame id and registered domain name to event loops.
|
||||||
/// This double indirection ensures that separate tabs do not share script threads,
|
/// This double indirection ensures that separate tabs do not share event loops,
|
||||||
/// even if the same domain is loaded in each.
|
/// even if the same domain is loaded in each.
|
||||||
script_channels: HashMap<FrameId, HashMap<String, Weak<ScriptChan>>>,
|
event_loops: HashMap<FrameId, HashMap<String, Weak<EventLoop>>>,
|
||||||
|
|
||||||
/// A list of all the pipelines. (See the `pipeline` module for more details.)
|
/// A list of all the pipelines. (See the `pipeline` module for more details.)
|
||||||
pipelines: HashMap<PipelineId, Pipeline>,
|
pipelines: HashMap<PipelineId, Pipeline>,
|
||||||
|
@ -367,30 +368,6 @@ enum ExitPipelineMode {
|
||||||
Force,
|
Force,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A script channel, that closes the script thread down when it is dropped
|
|
||||||
pub struct ScriptChan {
|
|
||||||
chan: IpcSender<ConstellationControlMsg>,
|
|
||||||
dont_send_or_sync: PhantomData<Rc<()>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for ScriptChan {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
let _ = self.chan.send(ConstellationControlMsg::ExitScriptThread);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ScriptChan {
|
|
||||||
pub fn send(&self, msg: ConstellationControlMsg) -> Result<(), IOError> {
|
|
||||||
self.chan.send(msg)
|
|
||||||
}
|
|
||||||
pub fn new(chan: IpcSender<ConstellationControlMsg>) -> Rc<ScriptChan> {
|
|
||||||
Rc::new(ScriptChan { chan: chan, dont_send_or_sync: PhantomData })
|
|
||||||
}
|
|
||||||
pub fn sender(&self) -> IpcSender<ConstellationControlMsg> {
|
|
||||||
self.chan.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A logger directed at the constellation from content processes
|
/// A logger directed at the constellation from content processes
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FromScriptLogger {
|
pub struct FromScriptLogger {
|
||||||
|
@ -532,7 +509,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
swmanager_chan: None,
|
swmanager_chan: None,
|
||||||
swmanager_receiver: swmanager_receiver,
|
swmanager_receiver: swmanager_receiver,
|
||||||
swmanager_sender: sw_mgr_clone,
|
swmanager_sender: sw_mgr_clone,
|
||||||
script_channels: HashMap::new(),
|
event_loops: HashMap::new(),
|
||||||
pipelines: HashMap::new(),
|
pipelines: HashMap::new(),
|
||||||
frames: HashMap::new(),
|
frames: HashMap::new(),
|
||||||
pending_frames: vec!(),
|
pending_frames: vec!(),
|
||||||
|
@ -608,17 +585,17 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
None => self.root_frame_id,
|
None => self.root_frame_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
let (script_channel, host) = match sandbox {
|
let (event_loop, host) = match sandbox {
|
||||||
IFrameSandboxState::IFrameSandboxed => (None, None),
|
IFrameSandboxState::IFrameSandboxed => (None, None),
|
||||||
IFrameSandboxState::IFrameUnsandboxed => match reg_host(&load_data.url) {
|
IFrameSandboxState::IFrameUnsandboxed => match reg_host(&load_data.url) {
|
||||||
None => (None, None),
|
None => (None, None),
|
||||||
Some(host) => {
|
Some(host) => {
|
||||||
let script_channel = self.script_channels.get(&top_level_frame_id)
|
let event_loop = self.event_loops.get(&top_level_frame_id)
|
||||||
.and_then(|map| map.get(host))
|
.and_then(|map| map.get(host))
|
||||||
.and_then(|weak| weak.upgrade());
|
.and_then(|weak| weak.upgrade());
|
||||||
match script_channel {
|
match event_loop {
|
||||||
None => (None, Some(String::from(host))),
|
None => (None, Some(String::from(host))),
|
||||||
Some(script_channel) => (Some(script_channel.clone()), None),
|
Some(event_loop) => (Some(event_loop.clone()), None),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -665,7 +642,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
time_profiler_chan: self.time_profiler_chan.clone(),
|
time_profiler_chan: self.time_profiler_chan.clone(),
|
||||||
mem_profiler_chan: self.mem_profiler_chan.clone(),
|
mem_profiler_chan: self.mem_profiler_chan.clone(),
|
||||||
window_size: initial_window_size,
|
window_size: initial_window_size,
|
||||||
script_chan: script_channel,
|
event_loop: event_loop,
|
||||||
load_data: load_data,
|
load_data: load_data,
|
||||||
device_pixel_ratio: self.window_size.device_pixel_ratio,
|
device_pixel_ratio: self.window_size.device_pixel_ratio,
|
||||||
pipeline_namespace_id: self.next_pipeline_namespace_id(),
|
pipeline_namespace_id: self.next_pipeline_namespace_id(),
|
||||||
|
@ -680,9 +657,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(host) = host {
|
if let Some(host) = host {
|
||||||
self.script_channels.entry(top_level_frame_id)
|
self.event_loops.entry(top_level_frame_id)
|
||||||
.or_insert_with(HashMap::new)
|
.or_insert_with(HashMap::new)
|
||||||
.insert(host, Rc::downgrade(&pipeline.script_chan));
|
.insert(host, Rc::downgrade(&pipeline.event_loop));
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(!self.pipelines.contains_key(&pipeline_id));
|
assert!(!self.pipelines.contains_key(&pipeline_id));
|
||||||
|
@ -970,7 +947,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
let msg = ConstellationControlMsg::SendEvent(pipeline_id, event);
|
let msg = ConstellationControlMsg::SendEvent(pipeline_id, event);
|
||||||
let result = match self.pipelines.get(&pipeline_id) {
|
let result = match self.pipelines.get(&pipeline_id) {
|
||||||
None => { debug!("Pipeline {:?} got event after closure.", pipeline_id); return; }
|
None => { debug!("Pipeline {:?} got event after closure.", pipeline_id); return; }
|
||||||
Some(pipeline) => pipeline.script_chan.send(msg),
|
Some(pipeline) => pipeline.event_loop.send(msg),
|
||||||
};
|
};
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
self.handle_send_error(pipeline_id, e);
|
self.handle_send_error(pipeline_id, e);
|
||||||
|
@ -1118,7 +1095,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
let msg = ConstellationControlMsg::DispatchStorageEvent(
|
let msg = ConstellationControlMsg::DispatchStorageEvent(
|
||||||
pipeline.id, storage, url.clone(), key.clone(), old_value.clone(), new_value.clone()
|
pipeline.id, storage, url.clone(), key.clone(), old_value.clone(), new_value.clone()
|
||||||
);
|
);
|
||||||
if let Err(err) = pipeline.script_chan.send(msg) {
|
if let Err(err) = pipeline.event_loop.send(msg) {
|
||||||
warn!("Failed to broadcast storage event to pipeline {} ({:?}).", pipeline.id, err);
|
warn!("Failed to broadcast storage event to pipeline {} ({:?}).", pipeline.id, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1327,7 +1304,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
match self.pipelines.get_mut(&pipeline_id) {
|
match self.pipelines.get_mut(&pipeline_id) {
|
||||||
Some(pipeline) => {
|
Some(pipeline) => {
|
||||||
pipeline.size = Some(*size);
|
pipeline.size = Some(*size);
|
||||||
pipeline.script_chan.send(msg)
|
pipeline.event_loop.send(msg)
|
||||||
}
|
}
|
||||||
None => return,
|
None => return,
|
||||||
}
|
}
|
||||||
|
@ -1352,7 +1329,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
child: pipeline_id,
|
child: pipeline_id,
|
||||||
};
|
};
|
||||||
let result = match self.pipelines.get(&parent_id) {
|
let result = match self.pipelines.get(&parent_id) {
|
||||||
Some(parent) => parent.script_chan.send(msg),
|
Some(parent) => parent.event_loop.send(msg),
|
||||||
None => return warn!("Parent {} frame loaded after closure.", parent_id),
|
None => return warn!("Parent {} frame loaded after closure.", parent_id),
|
||||||
};
|
};
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
|
@ -1432,7 +1409,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
None => return warn!("Script loaded url in closed iframe {}.", parent_pipeline_id),
|
None => return warn!("Script loaded url in closed iframe {}.", parent_pipeline_id),
|
||||||
};
|
};
|
||||||
|
|
||||||
let script_sender = parent_pipeline.script_chan.clone();
|
let script_sender = parent_pipeline.event_loop.clone();
|
||||||
|
|
||||||
let url = ServoUrl::parse("about:blank").expect("infallible");
|
let url = ServoUrl::parse("about:blank").expect("infallible");
|
||||||
Pipeline::new(new_pipeline_id,
|
Pipeline::new(new_pipeline_id,
|
||||||
|
@ -1475,7 +1452,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
AnimationTickType::Script => {
|
AnimationTickType::Script => {
|
||||||
let msg = ConstellationControlMsg::TickAllAnimations(pipeline_id);
|
let msg = ConstellationControlMsg::TickAllAnimations(pipeline_id);
|
||||||
match self.pipelines.get(&pipeline_id) {
|
match self.pipelines.get(&pipeline_id) {
|
||||||
Some(pipeline) => pipeline.script_chan.send(msg),
|
Some(pipeline) => pipeline.event_loop.send(msg),
|
||||||
None => return warn!("Pipeline {:?} got script tick after closure.", pipeline_id),
|
None => return warn!("Pipeline {:?} got script tick after closure.", pipeline_id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1548,7 +1525,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
// and issue an iframe load through there.
|
// and issue an iframe load through there.
|
||||||
let msg = ConstellationControlMsg::Navigate(parent_pipeline_id, frame_id, load_data, replace);
|
let msg = ConstellationControlMsg::Navigate(parent_pipeline_id, frame_id, load_data, replace);
|
||||||
let result = match self.pipelines.get(&parent_pipeline_id) {
|
let result = match self.pipelines.get(&parent_pipeline_id) {
|
||||||
Some(parent_pipeline) => parent_pipeline.script_chan.send(msg),
|
Some(parent_pipeline) => parent_pipeline.event_loop.send(msg),
|
||||||
None => {
|
None => {
|
||||||
warn!("Pipeline {:?} child loaded after closure", parent_pipeline_id);
|
warn!("Pipeline {:?} child loaded after closure", parent_pipeline_id);
|
||||||
return None;
|
return None;
|
||||||
|
@ -1694,7 +1671,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
let event = CompositorEvent::KeyEvent(ch, key, state, mods);
|
let event = CompositorEvent::KeyEvent(ch, key, state, mods);
|
||||||
let msg = ConstellationControlMsg::SendEvent(pipeline_id, event);
|
let msg = ConstellationControlMsg::SendEvent(pipeline_id, event);
|
||||||
let result = match self.pipelines.get(&pipeline_id) {
|
let result = match self.pipelines.get(&pipeline_id) {
|
||||||
Some(pipeline) => pipeline.script_chan.send(msg),
|
Some(pipeline) => pipeline.event_loop.send(msg),
|
||||||
None => return debug!("Pipeline {:?} got key event after closure.", pipeline_id),
|
None => return debug!("Pipeline {:?} got key event after closure.", pipeline_id),
|
||||||
};
|
};
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
|
@ -1716,7 +1693,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
if let Some(pipeline_id) = root_pipeline_id {
|
if let Some(pipeline_id) = root_pipeline_id {
|
||||||
let msg = ConstellationControlMsg::Reload(pipeline_id);
|
let msg = ConstellationControlMsg::Reload(pipeline_id);
|
||||||
let result = match self.pipelines.get(&pipeline_id) {
|
let result = match self.pipelines.get(&pipeline_id) {
|
||||||
Some(pipeline) => pipeline.script_chan.send(msg),
|
Some(pipeline) => pipeline.event_loop.send(msg),
|
||||||
None => return debug!("Pipeline {:?} got reload event after closure.", pipeline_id),
|
None => return debug!("Pipeline {:?} got reload event after closure.", pipeline_id),
|
||||||
};
|
};
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
|
@ -1728,7 +1705,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
fn handle_get_pipeline_title_msg(&mut self, pipeline_id: PipelineId) {
|
fn handle_get_pipeline_title_msg(&mut self, pipeline_id: PipelineId) {
|
||||||
let result = match self.pipelines.get(&pipeline_id) {
|
let result = match self.pipelines.get(&pipeline_id) {
|
||||||
None => return self.compositor_proxy.send(ToCompositorMsg::ChangePageTitle(pipeline_id, None)),
|
None => return self.compositor_proxy.send(ToCompositorMsg::ChangePageTitle(pipeline_id, None)),
|
||||||
Some(pipeline) => pipeline.script_chan.send(ConstellationControlMsg::GetTitle(pipeline_id)),
|
Some(pipeline) => pipeline.event_loop.send(ConstellationControlMsg::GetTitle(pipeline_id)),
|
||||||
};
|
};
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
self.handle_send_error(pipeline_id, e);
|
self.handle_send_error(pipeline_id, e);
|
||||||
|
@ -1791,7 +1768,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
// telling it to mark the iframe element as focused.
|
// telling it to mark the iframe element as focused.
|
||||||
let msg = ConstellationControlMsg::FocusIFrame(parent_pipeline_id, frame_id);
|
let msg = ConstellationControlMsg::FocusIFrame(parent_pipeline_id, frame_id);
|
||||||
let result = match self.pipelines.get(&parent_pipeline_id) {
|
let result = match self.pipelines.get(&parent_pipeline_id) {
|
||||||
Some(pipeline) => pipeline.script_chan.send(msg),
|
Some(pipeline) => pipeline.event_loop.send(msg),
|
||||||
None => return warn!("Pipeline {:?} focus after closure.", parent_pipeline_id),
|
None => return warn!("Pipeline {:?} focus after closure.", parent_pipeline_id),
|
||||||
};
|
};
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
|
@ -1853,7 +1830,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
visibility);
|
visibility);
|
||||||
let result = match self.pipelines.get(&parent_pipeline_id) {
|
let result = match self.pipelines.get(&parent_pipeline_id) {
|
||||||
None => return warn!("Parent pipeline {:?} closed", parent_pipeline_id),
|
None => return warn!("Parent pipeline {:?} closed", parent_pipeline_id),
|
||||||
Some(parent_pipeline) => parent_pipeline.script_chan.send(visibility_msg),
|
Some(parent_pipeline) => parent_pipeline.event_loop.send(visibility_msg),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
|
@ -1911,7 +1888,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd) => {
|
WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd) => {
|
||||||
let control_msg = ConstellationControlMsg::WebDriverScriptCommand(pipeline_id, cmd);
|
let control_msg = ConstellationControlMsg::WebDriverScriptCommand(pipeline_id, cmd);
|
||||||
let result = match self.pipelines.get(&pipeline_id) {
|
let result = match self.pipelines.get(&pipeline_id) {
|
||||||
Some(pipeline) => pipeline.script_chan.send(control_msg),
|
Some(pipeline) => pipeline.event_loop.send(control_msg),
|
||||||
None => return warn!("Pipeline {:?} ScriptCommand after closure.", pipeline_id),
|
None => return warn!("Pipeline {:?} ScriptCommand after closure.", pipeline_id),
|
||||||
};
|
};
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
|
@ -1919,14 +1896,14 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
WebDriverCommandMsg::SendKeys(pipeline_id, cmd) => {
|
WebDriverCommandMsg::SendKeys(pipeline_id, cmd) => {
|
||||||
let script_channel = match self.pipelines.get(&pipeline_id) {
|
let event_loop = match self.pipelines.get(&pipeline_id) {
|
||||||
Some(pipeline) => pipeline.script_chan.clone(),
|
Some(pipeline) => pipeline.event_loop.clone(),
|
||||||
None => return warn!("Pipeline {:?} SendKeys after closure.", pipeline_id),
|
None => return warn!("Pipeline {:?} SendKeys after closure.", pipeline_id),
|
||||||
};
|
};
|
||||||
for (key, mods, state) in cmd {
|
for (key, mods, state) in cmd {
|
||||||
let event = CompositorEvent::KeyEvent(None, key, state, mods);
|
let event = CompositorEvent::KeyEvent(None, key, state, mods);
|
||||||
let control_msg = ConstellationControlMsg::SendEvent(pipeline_id, event);
|
let control_msg = ConstellationControlMsg::SendEvent(pipeline_id, event);
|
||||||
if let Err(e) = script_channel.send(control_msg) {
|
if let Err(e) = event_loop.send(control_msg) {
|
||||||
return self.handle_send_error(pipeline_id, e);
|
return self.handle_send_error(pipeline_id, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2015,7 +1992,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
next_pipeline_id);
|
next_pipeline_id);
|
||||||
let result = match self.pipelines.get(&parent_pipeline_id) {
|
let result = match self.pipelines.get(&parent_pipeline_id) {
|
||||||
None => return warn!("Pipeline {:?} child traversed after closure.", parent_pipeline_id),
|
None => return warn!("Pipeline {:?} child traversed after closure.", parent_pipeline_id),
|
||||||
Some(pipeline) => pipeline.script_chan.send(msg),
|
Some(pipeline) => pipeline.event_loop.send(msg),
|
||||||
};
|
};
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
self.handle_send_error(parent_pipeline_id, e);
|
self.handle_send_error(parent_pipeline_id, e);
|
||||||
|
@ -2112,7 +2089,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
if let Some((parent_pipeline_id, _)) = pipeline.parent_info {
|
if let Some((parent_pipeline_id, _)) = pipeline.parent_info {
|
||||||
if let Some(parent_pipeline) = self.pipelines.get(&parent_pipeline_id) {
|
if let Some(parent_pipeline) = self.pipelines.get(&parent_pipeline_id) {
|
||||||
let msg = ConstellationControlMsg::FramedContentChanged(parent_pipeline_id, pipeline.frame_id);
|
let msg = ConstellationControlMsg::FramedContentChanged(parent_pipeline_id, pipeline.frame_id);
|
||||||
let _ = parent_pipeline.script_chan.send(msg);
|
let _ = parent_pipeline.event_loop.send(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2143,7 +2120,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
None => return warn!("Pipeline {:?} resized after closing.", pipeline_id),
|
None => return warn!("Pipeline {:?} resized after closing.", pipeline_id),
|
||||||
Some(pipeline) => pipeline,
|
Some(pipeline) => pipeline,
|
||||||
};
|
};
|
||||||
let _ = pipeline.script_chan.send(ConstellationControlMsg::Resize(
|
let _ = pipeline.event_loop.send(ConstellationControlMsg::Resize(
|
||||||
pipeline.id,
|
pipeline.id,
|
||||||
new_size,
|
new_size,
|
||||||
size_type
|
size_type
|
||||||
|
@ -2156,7 +2133,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
},
|
},
|
||||||
Some(pipeline) => pipeline,
|
Some(pipeline) => pipeline,
|
||||||
};
|
};
|
||||||
let _ = pipeline.script_chan.send(ConstellationControlMsg::ResizeInactive(
|
let _ = pipeline.event_loop.send(ConstellationControlMsg::ResizeInactive(
|
||||||
pipeline.id,
|
pipeline.id,
|
||||||
new_size
|
new_size
|
||||||
));
|
));
|
||||||
|
@ -2171,7 +2148,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
Some(pipeline) => pipeline,
|
Some(pipeline) => pipeline,
|
||||||
};
|
};
|
||||||
if pipeline.parent_info.is_none() {
|
if pipeline.parent_info.is_none() {
|
||||||
let _ = pipeline.script_chan.send(ConstellationControlMsg::Resize(
|
let _ = pipeline.event_loop.send(ConstellationControlMsg::Resize(
|
||||||
pipeline.id,
|
pipeline.id,
|
||||||
new_size,
|
new_size,
|
||||||
size_type
|
size_type
|
||||||
|
@ -2340,7 +2317,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
|
|
||||||
self.close_frame_children(frame_id, exit_mode);
|
self.close_frame_children(frame_id, exit_mode);
|
||||||
|
|
||||||
self.script_channels.remove(&frame_id);
|
self.event_loops.remove(&frame_id);
|
||||||
if self.frames.remove(&frame_id).is_none() {
|
if self.frames.remove(&frame_id).is_none() {
|
||||||
warn!("Closing frame {:?} twice.", frame_id);
|
warn!("Closing frame {:?} twice.", frame_id);
|
||||||
}
|
}
|
||||||
|
|
46
components/constellation/event_loop.rs
Normal file
46
components/constellation/event_loop.rs
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! This module contains the `EventLoop` type, which is the constellation's
|
||||||
|
//! view of a script thread. When an `EventLoop` is dropped, an `ExitScriptThread`
|
||||||
|
//! message is sent to the script thread, asking it to shut down.
|
||||||
|
|
||||||
|
use ipc_channel::ipc::IpcSender;
|
||||||
|
use script_traits::ConstellationControlMsg;
|
||||||
|
use std::io::Error as IOError;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
/// https://html.spec.whatwg.org/multipage/#event-loop
|
||||||
|
pub struct EventLoop {
|
||||||
|
script_chan: IpcSender<ConstellationControlMsg>,
|
||||||
|
dont_send_or_sync: PhantomData<Rc<()>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for EventLoop {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let _ = self.script_chan.send(ConstellationControlMsg::ExitScriptThread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventLoop {
|
||||||
|
/// Create a new event loop from the channel to its script thread.
|
||||||
|
pub fn new(script_chan: IpcSender<ConstellationControlMsg>) -> Rc<EventLoop> {
|
||||||
|
Rc::new(EventLoop {
|
||||||
|
script_chan: script_chan,
|
||||||
|
dont_send_or_sync: PhantomData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send a message to the event loop.
|
||||||
|
pub fn send(&self, msg: ConstellationControlMsg) -> Result<(), IOError> {
|
||||||
|
self.script_chan.send(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The underlying channel to the script thread.
|
||||||
|
pub fn sender(&self) -> IpcSender<ConstellationControlMsg> {
|
||||||
|
self.script_chan.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ extern crate style_traits;
|
||||||
extern crate webrender_traits;
|
extern crate webrender_traits;
|
||||||
|
|
||||||
mod constellation;
|
mod constellation;
|
||||||
|
mod event_loop;
|
||||||
mod pipeline;
|
mod pipeline;
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
mod sandboxing;
|
mod sandboxing;
|
||||||
|
|
|
@ -6,10 +6,10 @@ use bluetooth_traits::BluetoothRequest;
|
||||||
use compositing::CompositionPipeline;
|
use compositing::CompositionPipeline;
|
||||||
use compositing::CompositorProxy;
|
use compositing::CompositorProxy;
|
||||||
use compositing::compositor_thread::Msg as CompositorMsg;
|
use compositing::compositor_thread::Msg as CompositorMsg;
|
||||||
use constellation::ScriptChan;
|
|
||||||
use devtools_traits::{DevtoolsControlMsg, ScriptToDevtoolsControlMsg};
|
use devtools_traits::{DevtoolsControlMsg, ScriptToDevtoolsControlMsg};
|
||||||
use euclid::scale_factor::ScaleFactor;
|
use euclid::scale_factor::ScaleFactor;
|
||||||
use euclid::size::TypedSize2D;
|
use euclid::size::TypedSize2D;
|
||||||
|
use event_loop::EventLoop;
|
||||||
use gfx::font_cache_thread::FontCacheThread;
|
use gfx::font_cache_thread::FontCacheThread;
|
||||||
use gfx_traits::DevicePixel;
|
use gfx_traits::DevicePixel;
|
||||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
|
@ -43,7 +43,7 @@ pub struct Pipeline {
|
||||||
/// The ID of the frame that contains this Pipeline.
|
/// The ID of the frame that contains this Pipeline.
|
||||||
pub frame_id: FrameId,
|
pub frame_id: FrameId,
|
||||||
pub parent_info: Option<(PipelineId, FrameType)>,
|
pub parent_info: Option<(PipelineId, FrameType)>,
|
||||||
pub script_chan: Rc<ScriptChan>,
|
pub event_loop: Rc<EventLoop>,
|
||||||
/// A channel to layout, for performing reflows and shutdown.
|
/// A channel to layout, for performing reflows and shutdown.
|
||||||
pub layout_chan: IpcSender<LayoutControlMsg>,
|
pub layout_chan: IpcSender<LayoutControlMsg>,
|
||||||
/// A channel to the compositor.
|
/// A channel to the compositor.
|
||||||
|
@ -106,10 +106,9 @@ pub struct InitialPipelineState {
|
||||||
pub window_size: Option<TypedSize2D<f32, PagePx>>,
|
pub window_size: Option<TypedSize2D<f32, PagePx>>,
|
||||||
/// Information about the device pixel ratio.
|
/// Information about the device pixel ratio.
|
||||||
pub device_pixel_ratio: ScaleFactor<f32, ViewportPx, DevicePixel>,
|
pub device_pixel_ratio: ScaleFactor<f32, ViewportPx, DevicePixel>,
|
||||||
/// A channel to the script thread, if applicable.
|
/// The event loop to run in, if applicable. If this is `Some`,
|
||||||
/// If this is `None`, create a new script thread.
|
/// then `parent_info` must also be `Some`.
|
||||||
/// If this is `Some`, then reuse an existing script thread.
|
pub event_loop: Option<Rc<EventLoop>>,
|
||||||
pub script_chan: Option<Rc<ScriptChan>>,
|
|
||||||
/// Information about the page to load.
|
/// Information about the page to load.
|
||||||
pub load_data: LoadData,
|
pub load_data: LoadData,
|
||||||
/// The ID of the pipeline namespace for this script thread.
|
/// The ID of the pipeline namespace for this script thread.
|
||||||
|
@ -146,7 +145,7 @@ impl Pipeline {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let (script_chan, content_ports) = match state.script_chan {
|
let (script_chan, content_ports) = match state.event_loop {
|
||||||
Some(script_chan) => {
|
Some(script_chan) => {
|
||||||
let new_layout_info = NewLayoutInfo {
|
let new_layout_info = NewLayoutInfo {
|
||||||
parent_info: state.parent_info,
|
parent_info: state.parent_info,
|
||||||
|
@ -166,7 +165,7 @@ impl Pipeline {
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let (script_chan, script_port) = ipc::channel().expect("Pipeline script chan");
|
let (script_chan, script_port) = ipc::channel().expect("Pipeline script chan");
|
||||||
(ScriptChan::new(script_chan), Some((script_port, pipeline_port)))
|
(EventLoop::new(script_chan), Some((script_port, pipeline_port)))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -248,7 +247,7 @@ impl Pipeline {
|
||||||
pub fn new(id: PipelineId,
|
pub fn new(id: PipelineId,
|
||||||
frame_id: FrameId,
|
frame_id: FrameId,
|
||||||
parent_info: Option<(PipelineId, FrameType)>,
|
parent_info: Option<(PipelineId, FrameType)>,
|
||||||
script_chan: Rc<ScriptChan>,
|
event_loop: Rc<EventLoop>,
|
||||||
layout_chan: IpcSender<LayoutControlMsg>,
|
layout_chan: IpcSender<LayoutControlMsg>,
|
||||||
compositor_proxy: Box<CompositorProxy + 'static + Send>,
|
compositor_proxy: Box<CompositorProxy + 'static + Send>,
|
||||||
is_private: bool,
|
is_private: bool,
|
||||||
|
@ -260,7 +259,7 @@ impl Pipeline {
|
||||||
id: id,
|
id: id,
|
||||||
frame_id: frame_id,
|
frame_id: frame_id,
|
||||||
parent_info: parent_info,
|
parent_info: parent_info,
|
||||||
script_chan: script_chan,
|
event_loop: event_loop,
|
||||||
layout_chan: layout_chan,
|
layout_chan: layout_chan,
|
||||||
compositor_proxy: compositor_proxy,
|
compositor_proxy: compositor_proxy,
|
||||||
url: url,
|
url: url,
|
||||||
|
@ -294,25 +293,25 @@ impl Pipeline {
|
||||||
|
|
||||||
// Script thread handles shutting down layout, and layout handles shutting down the painter.
|
// Script thread handles shutting down layout, and layout handles shutting down the painter.
|
||||||
// For now, if the script thread has failed, we give up on clean shutdown.
|
// For now, if the script thread has failed, we give up on clean shutdown.
|
||||||
if let Err(e) = self.script_chan.send(ConstellationControlMsg::ExitPipeline(self.id)) {
|
if let Err(e) = self.event_loop.send(ConstellationControlMsg::ExitPipeline(self.id)) {
|
||||||
warn!("Sending script exit message failed ({}).", e);
|
warn!("Sending script exit message failed ({}).", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn freeze(&self) {
|
pub fn freeze(&self) {
|
||||||
if let Err(e) = self.script_chan.send(ConstellationControlMsg::Freeze(self.id)) {
|
if let Err(e) = self.event_loop.send(ConstellationControlMsg::Freeze(self.id)) {
|
||||||
warn!("Sending freeze message failed ({}).", e);
|
warn!("Sending freeze message failed ({}).", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn thaw(&self) {
|
pub fn thaw(&self) {
|
||||||
if let Err(e) = self.script_chan.send(ConstellationControlMsg::Thaw(self.id)) {
|
if let Err(e) = self.event_loop.send(ConstellationControlMsg::Thaw(self.id)) {
|
||||||
warn!("Sending freeze message failed ({}).", e);
|
warn!("Sending freeze message failed ({}).", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn force_exit(&self) {
|
pub fn force_exit(&self) {
|
||||||
if let Err(e) = self.script_chan.send(ConstellationControlMsg::ExitPipeline(self.id)) {
|
if let Err(e) = self.event_loop.send(ConstellationControlMsg::ExitPipeline(self.id)) {
|
||||||
warn!("Sending script exit message failed ({}).", e);
|
warn!("Sending script exit message failed ({}).", e);
|
||||||
}
|
}
|
||||||
if let Err(e) = self.layout_chan.send(LayoutControlMsg::ExitNow) {
|
if let Err(e) = self.layout_chan.send(LayoutControlMsg::ExitNow) {
|
||||||
|
@ -323,7 +322,7 @@ impl Pipeline {
|
||||||
pub fn to_sendable(&self) -> CompositionPipeline {
|
pub fn to_sendable(&self) -> CompositionPipeline {
|
||||||
CompositionPipeline {
|
CompositionPipeline {
|
||||||
id: self.id.clone(),
|
id: self.id.clone(),
|
||||||
script_chan: self.script_chan.sender(),
|
script_chan: self.event_loop.sender(),
|
||||||
layout_chan: self.layout_chan.clone(),
|
layout_chan: self.layout_chan.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,16 +346,16 @@ impl Pipeline {
|
||||||
let event = ConstellationControlMsg::MozBrowserEvent(self.id,
|
let event = ConstellationControlMsg::MozBrowserEvent(self.id,
|
||||||
child_id,
|
child_id,
|
||||||
event);
|
event);
|
||||||
if let Err(e) = self.script_chan.send(event) {
|
if let Err(e) = self.event_loop.send(event) {
|
||||||
warn!("Sending mozbrowser event to script failed ({}).", e);
|
warn!("Sending mozbrowser event to script failed ({}).", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn notify_visibility(&self) {
|
fn notify_visibility(&self) {
|
||||||
self.script_chan.send(ConstellationControlMsg::ChangeFrameVisibilityStatus(self.id, self.visible))
|
let script_msg = ConstellationControlMsg::ChangeFrameVisibilityStatus(self.id, self.visible);
|
||||||
.expect("Pipeline script chan");
|
let compositor_msg = CompositorMsg::PipelineVisibilityChanged(self.id, self.visible);
|
||||||
|
self.event_loop.send(script_msg).expect("Pipeline script chan");
|
||||||
self.compositor_proxy.send(CompositorMsg::PipelineVisibilityChanged(self.id, self.visible));
|
self.compositor_proxy.send(compositor_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_visibility(&mut self, visible: bool) {
|
pub fn change_visibility(&mut self, visible: bool) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue