mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
introduce a background-hang-monitor:
Mac-Os implementation of a thread sampler, Linux and Windows skeleton implementations.
This commit is contained in:
parent
7c65505df3
commit
4eb785cdc0
23 changed files with 1134 additions and 11 deletions
|
@ -11,6 +11,7 @@ name = "constellation"
|
|||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
background_hang_monitor = { path = "../background_hang_monitor"}
|
||||
backtrace = "0.3"
|
||||
bluetooth_traits = { path = "../bluetooth_traits" }
|
||||
canvas = {path = "../canvas"}
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
//!
|
||||
//! See https://github.com/servo/servo/issues/14704
|
||||
|
||||
use background_hang_monitor::HangMonitorRegister;
|
||||
use backtrace::Backtrace;
|
||||
use bluetooth_traits::BluetoothRequest;
|
||||
use canvas::canvas_paint_thread::CanvasPaintThread;
|
||||
|
@ -123,6 +124,7 @@ use keyboard_types::webdriver::Event as WebDriverInputEvent;
|
|||
use keyboard_types::KeyboardEvent;
|
||||
use layout_traits::LayoutThreadFactory;
|
||||
use log::{Level, LevelFilter, Log, Metadata, Record};
|
||||
use msg::constellation_msg::{BackgroundHangMonitorRegister, HangAlert};
|
||||
use msg::constellation_msg::{
|
||||
BrowsingContextId, HistoryStateId, PipelineId, TopLevelBrowsingContextId,
|
||||
};
|
||||
|
@ -200,6 +202,18 @@ pub struct Constellation<Message, LTF, STF> {
|
|||
/// This is the constellation's view of `script_sender`.
|
||||
script_receiver: Receiver<Result<(PipelineId, FromScriptMsg), IpcError>>,
|
||||
|
||||
/// A handle to register components for hang monitoring.
|
||||
/// None when in multiprocess mode.
|
||||
background_monitor_register: Option<Box<BackgroundHangMonitorRegister>>,
|
||||
|
||||
/// A channel for the background hang monitor to send messages
|
||||
/// to the constellation.
|
||||
background_hang_monitor_sender: IpcSender<HangAlert>,
|
||||
|
||||
/// A channel for the constellation to receiver messages
|
||||
/// from the background hang monitor.
|
||||
background_hang_monitor_receiver: Receiver<Result<HangAlert, IpcError>>,
|
||||
|
||||
/// An IPC channel for layout threads to send messages to the constellation.
|
||||
/// This is the layout threads' view of `layout_receiver`.
|
||||
layout_sender: IpcSender<FromLayoutMsg>,
|
||||
|
@ -587,6 +601,21 @@ where
|
|||
let script_receiver =
|
||||
route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(ipc_script_receiver);
|
||||
|
||||
let (background_hang_monitor_sender, ipc_bhm_receiver) =
|
||||
ipc::channel().expect("ipc channel failure");
|
||||
let background_hang_monitor_receiver =
|
||||
route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(ipc_bhm_receiver);
|
||||
|
||||
// If we are in multiprocess mode,
|
||||
// a dedicated per-process hang monitor will be initialized later inside the content process.
|
||||
// See run_content_process in servo/lib.rs
|
||||
let background_monitor_register = match opts::multiprocess() {
|
||||
true => None,
|
||||
false => Some(HangMonitorRegister::init(
|
||||
background_hang_monitor_sender.clone(),
|
||||
)),
|
||||
};
|
||||
|
||||
let (ipc_layout_sender, ipc_layout_receiver) =
|
||||
ipc::channel().expect("ipc channel failure");
|
||||
let layout_receiver =
|
||||
|
@ -602,6 +631,9 @@ where
|
|||
|
||||
let mut constellation: Constellation<Message, LTF, STF> = Constellation {
|
||||
script_sender: ipc_script_sender,
|
||||
background_hang_monitor_sender,
|
||||
background_hang_monitor_receiver,
|
||||
background_monitor_register,
|
||||
layout_sender: ipc_layout_sender,
|
||||
script_receiver: script_receiver,
|
||||
compositor_receiver: compositor_receiver,
|
||||
|
@ -768,6 +800,10 @@ where
|
|||
sender: self.script_sender.clone(),
|
||||
pipeline_id: pipeline_id,
|
||||
},
|
||||
background_monitor_register: self.background_monitor_register.clone(),
|
||||
background_hang_monitor_to_constellation_chan: self
|
||||
.background_hang_monitor_sender
|
||||
.clone(),
|
||||
layout_to_constellation_chan: self.layout_sender.clone(),
|
||||
scheduler_chan: self.scheduler_chan.clone(),
|
||||
compositor_proxy: self.compositor_proxy.clone(),
|
||||
|
@ -889,6 +925,7 @@ where
|
|||
#[derive(Debug)]
|
||||
enum Request {
|
||||
Script((PipelineId, FromScriptMsg)),
|
||||
BackgroundHangMonitor(HangAlert),
|
||||
Compositor(FromCompositorMsg),
|
||||
Layout(FromLayoutMsg),
|
||||
NetworkListener((PipelineId, FetchResponseMsg)),
|
||||
|
@ -910,6 +947,9 @@ where
|
|||
recv(self.script_receiver) -> msg => {
|
||||
msg.expect("Unexpected script channel panic in constellation").map(Request::Script)
|
||||
}
|
||||
recv(self.background_hang_monitor_receiver) -> msg => {
|
||||
msg.expect("Unexpected BHM channel panic in constellation").map(Request::BackgroundHangMonitor)
|
||||
}
|
||||
recv(self.compositor_receiver) -> msg => {
|
||||
Ok(Request::Compositor(msg.expect("Unexpected compositor channel panic in constellation")))
|
||||
}
|
||||
|
@ -936,6 +976,9 @@ where
|
|||
Request::Script(message) => {
|
||||
self.handle_request_from_script(message);
|
||||
},
|
||||
Request::BackgroundHangMonitor(message) => {
|
||||
self.handle_request_from_background_hang_monitor(message);
|
||||
},
|
||||
Request::Layout(message) => {
|
||||
self.handle_request_from_layout(message);
|
||||
},
|
||||
|
@ -948,6 +991,12 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_request_from_background_hang_monitor(&self, message: HangAlert) {
|
||||
// TODO: In case of a permanent hang being reported, add a "kill script" workflow,
|
||||
// via the embedder?
|
||||
warn!("Component hang alert: {:?}", message);
|
||||
}
|
||||
|
||||
fn handle_request_from_network_listener(&mut self, message: (PipelineId, FetchResponseMsg)) {
|
||||
let (id, message_) = message;
|
||||
let result = match self.pipelines.get(&id) {
|
||||
|
|
|
@ -18,6 +18,7 @@ use ipc_channel::Error;
|
|||
use layout_traits::LayoutThreadFactory;
|
||||
use metrics::PaintTimeMetrics;
|
||||
use msg::constellation_msg::TopLevelBrowsingContextId;
|
||||
use msg::constellation_msg::{BackgroundHangMonitorRegister, HangAlert};
|
||||
use msg::constellation_msg::{BrowsingContextId, HistoryStateId, PipelineId, PipelineNamespaceId};
|
||||
use net::image_cache::ImageCacheImpl;
|
||||
use net_traits::image_cache::ImageCache;
|
||||
|
@ -113,6 +114,13 @@ pub struct InitialPipelineState {
|
|||
/// A channel to the associated constellation.
|
||||
pub script_to_constellation_chan: ScriptToConstellationChan,
|
||||
|
||||
/// A handle to register components for hang monitoring.
|
||||
/// None when in multiprocess mode.
|
||||
pub background_monitor_register: Option<Box<BackgroundHangMonitorRegister>>,
|
||||
|
||||
/// A channel for the background hang monitor to send messages to the constellation.
|
||||
pub background_hang_monitor_to_constellation_chan: IpcSender<HangAlert>,
|
||||
|
||||
/// A channel for the layout thread to send messages to the constellation.
|
||||
pub layout_to_constellation_chan: IpcSender<LayoutMsg>,
|
||||
|
||||
|
@ -262,6 +270,9 @@ impl Pipeline {
|
|||
parent_pipeline_id: state.parent_pipeline_id,
|
||||
opener: state.opener,
|
||||
script_to_constellation_chan: state.script_to_constellation_chan.clone(),
|
||||
background_hang_monitor_to_constellation_chan: state
|
||||
.background_hang_monitor_to_constellation_chan
|
||||
.clone(),
|
||||
scheduler_chan: state.scheduler_chan,
|
||||
devtools_chan: script_to_devtools_chan,
|
||||
bluetooth_thread: state.bluetooth_thread,
|
||||
|
@ -295,7 +306,11 @@ impl Pipeline {
|
|||
if opts::multiprocess() {
|
||||
let _ = unprivileged_pipeline_content.spawn_multiprocess()?;
|
||||
} else {
|
||||
unprivileged_pipeline_content.start_all::<Message, LTF, STF>(false);
|
||||
// Should not be None in single-process mode.
|
||||
let register = state
|
||||
.background_monitor_register
|
||||
.expect("Couldn't start content, no background monitor has been initiated");
|
||||
unprivileged_pipeline_content.start_all::<Message, LTF, STF>(false, register);
|
||||
}
|
||||
|
||||
EventLoop::new(script_chan)
|
||||
|
@ -452,6 +467,7 @@ pub struct UnprivilegedPipelineContent {
|
|||
parent_pipeline_id: Option<PipelineId>,
|
||||
opener: Option<BrowsingContextId>,
|
||||
script_to_constellation_chan: ScriptToConstellationChan,
|
||||
background_hang_monitor_to_constellation_chan: IpcSender<HangAlert>,
|
||||
layout_to_constellation_chan: IpcSender<LayoutMsg>,
|
||||
scheduler_chan: IpcSender<TimerSchedulerMsg>,
|
||||
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
||||
|
@ -480,8 +496,11 @@ pub struct UnprivilegedPipelineContent {
|
|||
}
|
||||
|
||||
impl UnprivilegedPipelineContent {
|
||||
pub fn start_all<Message, LTF, STF>(self, wait_for_completion: bool)
|
||||
where
|
||||
pub fn start_all<Message, LTF, STF>(
|
||||
self,
|
||||
wait_for_completion: bool,
|
||||
background_hang_monitor_register: Box<BackgroundHangMonitorRegister>,
|
||||
) where
|
||||
LTF: LayoutThreadFactory<Message = Message>,
|
||||
STF: ScriptThreadFactory<Message = Message>,
|
||||
{
|
||||
|
@ -503,6 +522,7 @@ impl UnprivilegedPipelineContent {
|
|||
control_chan: self.script_chan.clone(),
|
||||
control_port: self.script_port,
|
||||
script_to_constellation_chan: self.script_to_constellation_chan.clone(),
|
||||
background_hang_monitor_register: background_hang_monitor_register.clone(),
|
||||
layout_to_constellation_chan: self.layout_to_constellation_chan.clone(),
|
||||
scheduler_chan: self.scheduler_chan,
|
||||
bluetooth_thread: self.bluetooth_thread,
|
||||
|
@ -529,6 +549,7 @@ impl UnprivilegedPipelineContent {
|
|||
self.parent_pipeline_id.is_some(),
|
||||
layout_pair,
|
||||
self.pipeline_port,
|
||||
background_hang_monitor_register,
|
||||
self.layout_to_constellation_chan,
|
||||
self.script_chan,
|
||||
image_cache.clone(),
|
||||
|
@ -626,6 +647,10 @@ impl UnprivilegedPipelineContent {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn background_hang_monitor_to_constellation_chan(&self) -> &IpcSender<HangAlert> {
|
||||
&self.background_hang_monitor_to_constellation_chan
|
||||
}
|
||||
|
||||
pub fn script_to_constellation_chan(&self) -> &ScriptToConstellationChan {
|
||||
&self.script_to_constellation_chan
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue