aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/config/opts.rs6
-rw-r--r--components/constellation/constellation.rs56
-rw-r--r--components/constellation/pipeline.rs51
-rw-r--r--components/layout_thread/lib.rs24
-rw-r--r--components/layout_thread_2020/lib.rs24
-rw-r--r--components/layout_traits/lib.rs2
-rw-r--r--components/script/script_thread.rs33
-rw-r--r--components/script_layout_interface/message.rs2
-rw-r--r--components/script_traits/lib.rs2
9 files changed, 126 insertions, 74 deletions
diff --git a/components/config/opts.rs b/components/config/opts.rs
index a56e8e27172..9bdd7bc9061 100644
--- a/components/config/opts.rs
+++ b/components/config/opts.rs
@@ -136,6 +136,9 @@ pub struct Opts {
/// Whether we're running in multiprocess mode.
pub multiprocess: bool,
+ /// Whether we want background hang monitor enabled or not
+ pub background_hang_monitor: bool,
+
/// Whether we're running inside the sandbox.
pub sandbox: bool,
@@ -545,6 +548,7 @@ pub fn default_opts() -> Opts {
initial_window_size: Size2D::new(1024, 740),
user_agent: default_user_agent_string(DEFAULT_USER_AGENT).into(),
multiprocess: false,
+ background_hang_monitor: false,
random_pipeline_closure_probability: None,
random_pipeline_closure_seed: None,
sandbox: false,
@@ -669,6 +673,7 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR
"NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)",
);
opts.optflag("M", "multiprocess", "Run in multiprocess mode");
+ opts.optflag("B", "bhm", "Background Hang Monitor enabled");
opts.optflag("S", "sandbox", "Run in a sandbox if multiprocess");
opts.optopt(
"",
@@ -965,6 +970,7 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR
initial_window_size: initial_window_size,
user_agent: user_agent,
multiprocess: opt_match.opt_present("M"),
+ background_hang_monitor: opt_match.opt_present("B"),
sandbox: opt_match.opt_present("S"),
random_pipeline_closure_probability: random_pipeline_closure_probability,
random_pipeline_closure_seed: random_pipeline_closure_seed,
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs
index 4036d3b392e..0df1a28c15c 100644
--- a/components/constellation/constellation.rs
+++ b/components/constellation/constellation.rs
@@ -282,11 +282,11 @@ pub struct Constellation<Message, LTF, STF> {
/// A channel for the background hang monitor to send messages
/// to the constellation.
- background_hang_monitor_sender: IpcSender<HangMonitorAlert>,
+ background_hang_monitor_sender: Option<IpcSender<HangMonitorAlert>>,
/// A channel for the constellation to receiver messages
/// from the background hang monitor.
- background_hang_monitor_receiver: Receiver<Result<HangMonitorAlert, IpcError>>,
+ background_hang_monitor_receiver: Option<Receiver<Result<HangMonitorAlert, IpcError>>>,
/// An IPC channel for layout threads to send messages to the constellation.
/// This is the layout threads' view of `layout_receiver`.
@@ -849,28 +849,42 @@ where
ipc_scheduler_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);
+ let (background_hang_monitor_sender, background_hang_monitor_receiver) =
+ if opts::get().background_hang_monitor {
+ let (bhm_sender, ipc_bhm_receiver) =
+ ipc::channel().expect("ipc channel failure");
+ (
+ Some(bhm_sender),
+ Some(route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(
+ ipc_bhm_receiver,
+ )),
+ )
+ } else {
+ (None, None)
+ };
// 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, sampler_chan) = if opts::multiprocess() {
- (None, vec![])
- } else {
- let (sampling_profiler_control, sampling_profiler_port) =
- ipc::channel().expect("ipc channel failure");
-
- (
- Some(HangMonitorRegister::init(
- background_hang_monitor_sender.clone(),
- sampling_profiler_port,
- )),
- vec![sampling_profiler_control],
- )
- };
+ let (background_monitor_register, sampler_chan) =
+ if opts::multiprocess() || !opts::get().background_hang_monitor {
+ (None, vec![])
+ } else {
+ let (sampling_profiler_control, sampling_profiler_port) =
+ ipc::channel().expect("ipc channel failure");
+ if let Some(bhm_sender) = background_hang_monitor_sender.clone() {
+ (
+ Some(HangMonitorRegister::init(
+ bhm_sender,
+ sampling_profiler_port,
+ )),
+ vec![sampling_profiler_control],
+ )
+ } else {
+ warn!("No BHM sender found in BHM mode.");
+ (None, vec![])
+ }
+ };
let (ipc_layout_sender, ipc_layout_receiver) =
ipc::channel().expect("ipc channel failure");
@@ -1413,7 +1427,7 @@ where
recv(self.script_receiver) -> msg => {
msg.expect("Unexpected script channel panic in constellation").map(Request::Script)
}
- recv(self.background_hang_monitor_receiver) -> msg => {
+ recv(self.background_hang_monitor_receiver.as_ref().unwrap_or(&never())) -> msg => {
msg.expect("Unexpected BHM channel panic in constellation").map(Request::BackgroundHangMonitor)
}
recv(self.compositor_receiver) -> msg => {
diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs
index c56d49962ee..665ea177e79 100644
--- a/components/constellation/pipeline.rs
+++ b/components/constellation/pipeline.rs
@@ -131,7 +131,7 @@ pub struct InitialPipelineState {
pub background_monitor_register: Option<Box<dyn BackgroundHangMonitorRegister>>,
/// A channel for the background hang monitor to send messages to the constellation.
- pub background_hang_monitor_to_constellation_chan: IpcSender<HangMonitorAlert>,
+ pub background_hang_monitor_to_constellation_chan: Option<IpcSender<HangMonitorAlert>>,
/// A channel for the layout thread to send messages to the constellation.
pub layout_to_constellation_chan: IpcSender<LayoutMsg>,
@@ -319,15 +319,24 @@ impl Pipeline {
Some(sampler_chan)
} else {
// 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,
- state.event_loop_waker,
- );
- None
+ if opts::get().background_hang_monitor {
+ 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,
+ Some(register),
+ state.event_loop_waker,
+ );
+ None
+ } else {
+ unprivileged_pipeline_content.start_all::<Message, LTF, STF>(
+ false,
+ None,
+ state.event_loop_waker,
+ );
+ None
+ }
};
(EventLoop::new(script_chan), sampler_chan)
@@ -488,7 +497,7 @@ pub struct UnprivilegedPipelineContent {
opener: Option<BrowsingContextId>,
namespace_request_sender: IpcSender<PipelineNamespaceRequest>,
script_to_constellation_chan: ScriptToConstellationChan,
- background_hang_monitor_to_constellation_chan: IpcSender<HangMonitorAlert>,
+ background_hang_monitor_to_constellation_chan: Option<IpcSender<HangMonitorAlert>>,
sampling_profiler_port: Option<IpcReceiver<SamplerControlMsg>>,
layout_to_constellation_chan: IpcSender<LayoutMsg>,
scheduler_chan: IpcSender<TimerSchedulerMsg>,
@@ -520,7 +529,7 @@ impl UnprivilegedPipelineContent {
pub fn start_all<Message, LTF, STF>(
self,
wait_for_completion: bool,
- background_hang_monitor_register: Box<dyn BackgroundHangMonitorRegister>,
+ background_hang_monitor_register: Option<Box<dyn BackgroundHangMonitorRegister>>,
event_loop_waker: Option<Box<dyn EventLoopWaker>>,
) where
LTF: LayoutThreadFactory<Message = Message>,
@@ -730,13 +739,17 @@ impl UnprivilegedPipelineContent {
pub fn register_with_background_hang_monitor(
&mut self,
- ) -> Box<dyn BackgroundHangMonitorRegister> {
- HangMonitorRegister::init(
- self.background_hang_monitor_to_constellation_chan.clone(),
- self.sampling_profiler_port
- .take()
- .expect("no sampling profiler?"),
- )
+ ) -> Option<Box<dyn BackgroundHangMonitorRegister>> {
+ self.background_hang_monitor_to_constellation_chan
+ .clone()
+ .map(|bhm| {
+ HangMonitorRegister::init(
+ bhm.clone(),
+ self.sampling_profiler_port
+ .take()
+ .expect("no sampling profiler?"),
+ )
+ })
}
pub fn script_to_constellation_chan(&self) -> &ScriptToConstellationChan {
diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs
index b5b45993c2b..127eab08914 100644
--- a/components/layout_thread/lib.rs
+++ b/components/layout_thread/lib.rs
@@ -159,7 +159,7 @@ pub struct LayoutThread {
font_cache_sender: IpcSender<()>,
/// A means of communication with the background hang monitor.
- background_hang_monitor: Box<dyn BackgroundHangMonitor>,
+ background_hang_monitor: Option<Box<dyn BackgroundHangMonitor>>,
/// The channel on which messages can be sent to the constellation.
constellation_chan: IpcSender<ConstellationMsg>,
@@ -292,7 +292,7 @@ impl LayoutThreadFactory for LayoutThread {
is_iframe: bool,
chan: (Sender<Msg>, Receiver<Msg>),
pipeline_port: IpcReceiver<LayoutControlMsg>,
- background_hang_monitor_register: Box<dyn BackgroundHangMonitorRegister>,
+ background_hang_monitor_register: Option<Box<dyn BackgroundHangMonitorRegister>>,
constellation_chan: IpcSender<ConstellationMsg>,
script_chan: IpcSender<ConstellationControlMsg>,
image_cache: Arc<dyn ImageCache>,
@@ -326,12 +326,13 @@ impl LayoutThreadFactory for LayoutThread {
// Ensures layout thread is destroyed before we send shutdown message
let sender = chan.0;
- let background_hang_monitor = background_hang_monitor_register
- .register_component(
+ let background_hang_monitor = background_hang_monitor_register.map(|bhm| {
+ bhm.register_component(
MonitoredComponentId(id, MonitoredComponentType::Layout),
Duration::from_millis(1000),
Duration::from_millis(5000),
- );
+ )
+ });
let layout = LayoutThread::new(
id,
@@ -510,7 +511,7 @@ impl LayoutThread {
is_iframe: bool,
port: Receiver<Msg>,
pipeline_port: IpcReceiver<LayoutControlMsg>,
- background_hang_monitor: Box<dyn BackgroundHangMonitor>,
+ background_hang_monitor: Option<Box<dyn BackgroundHangMonitor>>,
constellation_chan: IpcSender<ConstellationMsg>,
script_chan: IpcSender<ConstellationControlMsg>,
image_cache: Arc<dyn ImageCache>,
@@ -708,7 +709,8 @@ impl LayoutThread {
Msg::GetRunningAnimations(..) => LayoutHangAnnotation::GetRunningAnimations,
};
self.background_hang_monitor
- .notify_activity(HangAnnotation::Layout(hang_annotation));
+ .as_ref()
+ .map(|bhm| bhm.notify_activity(HangAnnotation::Layout(hang_annotation)));
}
/// Receives and dispatches messages from the script and constellation threads
@@ -720,7 +722,9 @@ impl LayoutThread {
}
// Notify the background-hang-monitor we are waiting for an event.
- self.background_hang_monitor.notify_wait();
+ self.background_hang_monitor
+ .as_ref()
+ .map(|bhm| bhm.notify_wait());
let request = select! {
recv(self.pipeline_port) -> msg => Request::FromPipeline(msg.unwrap()),
@@ -995,7 +999,9 @@ impl LayoutThread {
);
self.root_flow.borrow_mut().take();
- self.background_hang_monitor.unregister();
+ self.background_hang_monitor
+ .as_ref()
+ .map(|bhm| bhm.unregister());
}
fn handle_add_stylesheet(&self, stylesheet: &Stylesheet, guard: &SharedRwLockReadGuard) {
diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs
index be24d768595..2972f7ef46f 100644
--- a/components/layout_thread_2020/lib.rs
+++ b/components/layout_thread_2020/lib.rs
@@ -137,7 +137,7 @@ pub struct LayoutThread {
font_cache_sender: IpcSender<()>,
/// A means of communication with the background hang monitor.
- background_hang_monitor: Box<dyn BackgroundHangMonitor>,
+ background_hang_monitor: Option<Box<dyn BackgroundHangMonitor>>,
/// The channel on which messages can be sent to the script thread.
script_chan: IpcSender<ConstellationControlMsg>,
@@ -247,7 +247,7 @@ impl LayoutThreadFactory for LayoutThread {
is_iframe: bool,
chan: (Sender<Msg>, Receiver<Msg>),
pipeline_port: IpcReceiver<LayoutControlMsg>,
- background_hang_monitor_register: Box<dyn BackgroundHangMonitorRegister>,
+ background_hang_monitor_register: Option<Box<dyn BackgroundHangMonitorRegister>>,
constellation_chan: IpcSender<ConstellationMsg>,
script_chan: IpcSender<ConstellationControlMsg>,
image_cache: Arc<dyn ImageCache>,
@@ -281,12 +281,13 @@ impl LayoutThreadFactory for LayoutThread {
// Ensures layout thread is destroyed before we send shutdown message
let sender = chan.0;
- let background_hang_monitor = background_hang_monitor_register
- .register_component(
+ let background_hang_monitor = background_hang_monitor_register.map(|bhm| {
+ bhm.register_component(
MonitoredComponentId(id, MonitoredComponentType::Layout),
Duration::from_millis(1000),
Duration::from_millis(5000),
- );
+ )
+ });
let layout = LayoutThread::new(
id,
@@ -463,7 +464,7 @@ impl LayoutThread {
is_iframe: bool,
port: Receiver<Msg>,
pipeline_port: IpcReceiver<LayoutControlMsg>,
- background_hang_monitor: Box<dyn BackgroundHangMonitor>,
+ background_hang_monitor: Option<Box<dyn BackgroundHangMonitor>>,
constellation_chan: IpcSender<ConstellationMsg>,
script_chan: IpcSender<ConstellationControlMsg>,
image_cache: Arc<dyn ImageCache>,
@@ -648,7 +649,8 @@ impl LayoutThread {
Msg::GetRunningAnimations(..) => LayoutHangAnnotation::GetRunningAnimations,
};
self.background_hang_monitor
- .notify_activity(HangAnnotation::Layout(hang_annotation));
+ .as_ref()
+ .map(|bhm| bhm.notify_activity(HangAnnotation::Layout(hang_annotation)));
}
/// Receives and dispatches messages from the script and constellation threads
@@ -660,7 +662,9 @@ impl LayoutThread {
}
// Notify the background-hang-monitor we are waiting for an event.
- self.background_hang_monitor.notify_wait();
+ self.background_hang_monitor
+ .as_ref()
+ .map(|bhm| bhm.notify_wait());
let request = select! {
recv(self.pipeline_port) -> msg => Request::FromPipeline(msg.unwrap()),
@@ -895,7 +899,9 @@ impl LayoutThread {
}
fn exit_now(&mut self) {
- self.background_hang_monitor.unregister();
+ self.background_hang_monitor
+ .as_ref()
+ .map(|bhm| bhm.unregister());
}
fn handle_add_stylesheet(&self, stylesheet: &Stylesheet, guard: &SharedRwLockReadGuard) {
diff --git a/components/layout_traits/lib.rs b/components/layout_traits/lib.rs
index 942d37a8c87..2ee0021df96 100644
--- a/components/layout_traits/lib.rs
+++ b/components/layout_traits/lib.rs
@@ -36,7 +36,7 @@ pub trait LayoutThreadFactory {
is_iframe: bool,
chan: (Sender<Self::Message>, Receiver<Self::Message>),
pipeline_port: IpcReceiver<LayoutControlMsg>,
- background_hang_monitor: Box<dyn BackgroundHangMonitorRegister>,
+ background_hang_monitor: Option<Box<dyn BackgroundHangMonitorRegister>>,
constellation_chan: IpcSender<ConstellationMsg>,
script_chan: IpcSender<ConstellationControlMsg>,
image_cache: Arc<dyn ImageCache>,
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index bcc7b10f8c7..118b4b4f653 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -545,9 +545,9 @@ pub struct ScriptThread {
task_queue: TaskQueue<MainThreadScriptMsg>,
/// A handle to register associated layout threads for hang-monitoring.
- background_hang_monitor_register: Box<dyn BackgroundHangMonitorRegister>,
+ background_hang_monitor_register: Option<Box<dyn BackgroundHangMonitorRegister>>,
/// The dedicated means of communication with the background-hang-monitor for this script-thread.
- background_hang_monitor: Box<dyn BackgroundHangMonitor>,
+ background_hang_monitor: Option<Box<dyn BackgroundHangMonitor>>,
/// A channel to hand out to script thread-based entities that need to be able to enqueue
/// events in the event queue.
@@ -1262,18 +1262,20 @@ impl ScriptThread {
let devtools_port =
ROUTER.route_ipc_receiver_to_new_crossbeam_receiver(ipc_devtools_receiver);
- // Ask the router to proxy IPC messages from the control port to us.
- let control_port = ROUTER.route_ipc_receiver_to_new_crossbeam_receiver(state.control_port);
-
let (image_cache_channel, image_cache_port) = unbounded();
let task_queue = TaskQueue::new(port, chan.clone());
- let background_hang_monitor = state.background_hang_monitor_register.register_component(
- MonitoredComponentId(state.id, MonitoredComponentType::Script),
- Duration::from_millis(1000),
- Duration::from_millis(5000),
- );
+ let background_hang_monitor = state.background_hang_monitor_register.clone().map(|bhm| {
+ bhm.register_component(
+ MonitoredComponentId(state.id.clone(), MonitoredComponentType::Script),
+ Duration::from_millis(1000),
+ Duration::from_millis(5000),
+ )
+ });
+
+ // Ask the router to proxy IPC messages from the control port to us.
+ let control_port = ROUTER.route_ipc_receiver_to_new_crossbeam_receiver(state.control_port);
ScriptThread {
documents: DomRefCell::new(Documents::new()),
@@ -1408,7 +1410,9 @@ impl ScriptThread {
let mut sequential = vec![];
// Notify the background-hang-monitor we are waiting for an event.
- self.background_hang_monitor.notify_wait();
+ self.background_hang_monitor
+ .as_ref()
+ .map(|bhm| bhm.notify_wait());
// Receive at least one message so we don't spinloop.
debug!("Waiting for event.");
@@ -1662,7 +1666,8 @@ impl ScriptThread {
ScriptThreadEventCategory::PortMessage => ScriptHangAnnotation::PortMessage,
};
self.background_hang_monitor
- .notify_activity(HangAnnotation::Script(hang_annotation));
+ .as_ref()
+ .map(|bhm| bhm.notify_activity(HangAnnotation::Script(hang_annotation)));
}
fn message_to_pipeline(&self, msg: &MixedMessage) -> Option<PipelineId> {
@@ -2882,7 +2887,9 @@ impl ScriptThread {
self.handle_exit_pipeline_msg(pipeline_id, DiscardBrowsingContext::Yes);
}
- self.background_hang_monitor.unregister();
+ self.background_hang_monitor
+ .as_ref()
+ .map(|bhm| bhm.unregister());
debug!("Exited script thread.");
}
diff --git a/components/script_layout_interface/message.rs b/components/script_layout_interface/message.rs
index 9e52083c9d4..e48ac42f509 100644
--- a/components/script_layout_interface/message.rs
+++ b/components/script_layout_interface/message.rs
@@ -226,7 +226,7 @@ pub struct LayoutThreadInit {
pub is_parent: bool,
pub layout_pair: (Sender<Msg>, Receiver<Msg>),
pub pipeline_port: IpcReceiver<LayoutControlMsg>,
- pub background_hang_monitor_register: Box<dyn BackgroundHangMonitorRegister>,
+ pub background_hang_monitor_register: Option<Box<dyn BackgroundHangMonitorRegister>>,
pub constellation_chan: IpcSender<ConstellationMsg>,
pub script_chan: IpcSender<ConstellationControlMsg>,
pub image_cache: Arc<dyn ImageCache>,
diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs
index 7f6ecece10b..d928335f8e3 100644
--- a/components/script_traits/lib.rs
+++ b/components/script_traits/lib.rs
@@ -644,7 +644,7 @@ pub struct InitialScriptState {
/// A channel on which messages can be sent to the constellation from script.
pub script_to_constellation_chan: ScriptToConstellationChan,
/// A handle to register script-(and associated layout-)threads for hang monitoring.
- pub background_hang_monitor_register: Box<dyn BackgroundHangMonitorRegister>,
+ pub background_hang_monitor_register: Option<Box<dyn BackgroundHangMonitorRegister>>,
/// A sender for the layout thread to communicate to the constellation.
pub layout_to_constellation_chan: IpcSender<LayoutMsg>,
/// A channel to schedule timer events.