mirror of
https://github.com/servo/servo.git
synced 2025-09-10 15:08:21 +01:00
compositor: Preserve CompositorMsg deserialization errors (#38972)
Forward any deserialization errors to the receiver, instead of panicking on the router thread. This change was previously part of #38782, which got reverted, since generic channels don't support custom router callbacks yet. Propagating the error is still something we want, and landing this separately will reduce the diff of the PR that introduces generic callbacks. Testing: Should be covered by existing tests. Also manually tested https://github.com/servo/servo/issues/38939 --------- Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com> Signed-off-by: Jonathan Schwender <55576758+jschwe@users.noreply.github.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
eaab71d335
commit
a5d890c13a
4 changed files with 25 additions and 10 deletions
|
@ -13,7 +13,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
use base::Epoch;
|
use base::Epoch;
|
||||||
use base::cross_process_instant::CrossProcessInstant;
|
use base::cross_process_instant::CrossProcessInstant;
|
||||||
use base::generic_channel::GenericSender;
|
use base::generic_channel::{GenericSender, RoutedReceiver};
|
||||||
use base::id::{PipelineId, WebViewId};
|
use base::id::{PipelineId, WebViewId};
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use compositing_traits::display_list::{CompositorDisplayListInfo, ScrollTree, ScrollType};
|
use compositing_traits::display_list::{CompositorDisplayListInfo, ScrollTree, ScrollType};
|
||||||
|
@ -23,7 +23,7 @@ use compositing_traits::{
|
||||||
WebViewTrait,
|
WebViewTrait,
|
||||||
};
|
};
|
||||||
use constellation_traits::{EmbedderToConstellationMessage, PaintMetricEvent};
|
use constellation_traits::{EmbedderToConstellationMessage, PaintMetricEvent};
|
||||||
use crossbeam_channel::{Receiver, Sender};
|
use crossbeam_channel::Sender;
|
||||||
use dpi::PhysicalSize;
|
use dpi::PhysicalSize;
|
||||||
use embedder_traits::{CompositorHitTestResult, InputEvent, ShutdownState, ViewportDetails};
|
use embedder_traits::{CompositorHitTestResult, InputEvent, ShutdownState, ViewportDetails};
|
||||||
use euclid::{Point2D, Rect, Scale, Size2D, Transform3D};
|
use euclid::{Point2D, Rect, Scale, Size2D, Transform3D};
|
||||||
|
@ -93,7 +93,7 @@ pub struct ServoRenderer {
|
||||||
shutdown_state: Rc<Cell<ShutdownState>>,
|
shutdown_state: Rc<Cell<ShutdownState>>,
|
||||||
|
|
||||||
/// The port on which we receive messages.
|
/// The port on which we receive messages.
|
||||||
compositor_receiver: Receiver<CompositorMsg>,
|
compositor_receiver: RoutedReceiver<CompositorMsg>,
|
||||||
|
|
||||||
/// The channel on which messages can be sent to the constellation.
|
/// The channel on which messages can be sent to the constellation.
|
||||||
pub(crate) constellation_sender: Sender<EmbedderToConstellationMessage>,
|
pub(crate) constellation_sender: Sender<EmbedderToConstellationMessage>,
|
||||||
|
@ -1394,7 +1394,7 @@ impl IOCompositor {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the message receiver for this [`IOCompositor`].
|
/// Get the message receiver for this [`IOCompositor`].
|
||||||
pub fn receiver(&self) -> Ref<'_, Receiver<CompositorMsg>> {
|
pub fn receiver(&self) -> Ref<'_, RoutedReceiver<CompositorMsg>> {
|
||||||
Ref::map(self.global.borrow(), |global| &global.compositor_receiver)
|
Ref::map(self.global.borrow(), |global| &global.compositor_receiver)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,11 @@
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use base::generic_channel::RoutedReceiver;
|
||||||
use compositing_traits::rendering_context::RenderingContext;
|
use compositing_traits::rendering_context::RenderingContext;
|
||||||
use compositing_traits::{CompositorMsg, CompositorProxy};
|
use compositing_traits::{CompositorMsg, CompositorProxy};
|
||||||
use constellation_traits::EmbedderToConstellationMessage;
|
use constellation_traits::EmbedderToConstellationMessage;
|
||||||
use crossbeam_channel::{Receiver, Sender};
|
use crossbeam_channel::Sender;
|
||||||
use embedder_traits::{EventLoopWaker, ShutdownState};
|
use embedder_traits::{EventLoopWaker, ShutdownState};
|
||||||
use profile_traits::{mem, time};
|
use profile_traits::{mem, time};
|
||||||
use webrender::RenderApi;
|
use webrender::RenderApi;
|
||||||
|
@ -32,7 +33,7 @@ pub struct InitialCompositorState {
|
||||||
/// A channel to the compositor.
|
/// A channel to the compositor.
|
||||||
pub sender: CompositorProxy,
|
pub sender: CompositorProxy,
|
||||||
/// A port on which messages inbound to the compositor can be received.
|
/// A port on which messages inbound to the compositor can be received.
|
||||||
pub receiver: Receiver<CompositorMsg>,
|
pub receiver: RoutedReceiver<CompositorMsg>,
|
||||||
/// A channel to the constellation.
|
/// A channel to the constellation.
|
||||||
pub constellation_chan: Sender<EmbedderToConstellationMessage>,
|
pub constellation_chan: Sender<EmbedderToConstellationMessage>,
|
||||||
/// A channel to the time profiler thread.
|
/// A channel to the time profiler thread.
|
||||||
|
|
|
@ -33,6 +33,7 @@ use std::rc::{Rc, Weak};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
|
use base::generic_channel::RoutedReceiver;
|
||||||
pub use base::id::WebViewId;
|
pub use base::id::WebViewId;
|
||||||
use base::id::{PipelineNamespace, PipelineNamespaceId};
|
use base::id::{PipelineNamespace, PipelineNamespaceId};
|
||||||
#[cfg(feature = "bluetooth")]
|
#[cfg(feature = "bluetooth")]
|
||||||
|
@ -544,7 +545,12 @@ impl Servo {
|
||||||
let mut compositor = self.compositor.borrow_mut();
|
let mut compositor = self.compositor.borrow_mut();
|
||||||
let mut messages = Vec::new();
|
let mut messages = Vec::new();
|
||||||
while let Ok(message) = compositor.receiver().try_recv() {
|
while let Ok(message) = compositor.receiver().try_recv() {
|
||||||
messages.push(message);
|
match message {
|
||||||
|
Ok(message) => messages.push(message),
|
||||||
|
Err(error) => {
|
||||||
|
warn!("Router deserialization error: {error}. Ignoring this CompositorMsg.")
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
compositor.handle_messages(messages);
|
compositor.handle_messages(messages);
|
||||||
}
|
}
|
||||||
|
@ -1095,7 +1101,7 @@ fn create_embedder_channel(
|
||||||
|
|
||||||
fn create_compositor_channel(
|
fn create_compositor_channel(
|
||||||
event_loop_waker: Box<dyn EventLoopWaker>,
|
event_loop_waker: Box<dyn EventLoopWaker>,
|
||||||
) -> (CompositorProxy, Receiver<CompositorMsg>) {
|
) -> (CompositorProxy, RoutedReceiver<CompositorMsg>) {
|
||||||
let (sender, receiver) = unbounded();
|
let (sender, receiver) = unbounded();
|
||||||
|
|
||||||
let (compositor_ipc_sender, compositor_ipc_receiver) =
|
let (compositor_ipc_sender, compositor_ipc_receiver) =
|
||||||
|
@ -1112,7 +1118,7 @@ fn create_compositor_channel(
|
||||||
ROUTER.add_typed_route(
|
ROUTER.add_typed_route(
|
||||||
compositor_ipc_receiver,
|
compositor_ipc_receiver,
|
||||||
Box::new(move |message| {
|
Box::new(move |message| {
|
||||||
compositor_proxy_clone.send(message.expect("Could not convert Compositor message"));
|
compositor_proxy_clone.route_msg(message);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ use crate::viewport_description::ViewportDescription;
|
||||||
/// Sends messages to the compositor.
|
/// Sends messages to the compositor.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CompositorProxy {
|
pub struct CompositorProxy {
|
||||||
pub sender: Sender<CompositorMsg>,
|
pub sender: Sender<Result<CompositorMsg, ipc_channel::Error>>,
|
||||||
/// Access to [`Self::sender`] that is possible to send across an IPC
|
/// Access to [`Self::sender`] that is possible to send across an IPC
|
||||||
/// channel. These messages are routed via the router thread to
|
/// channel. These messages are routed via the router thread to
|
||||||
/// [`Self::sender`].
|
/// [`Self::sender`].
|
||||||
|
@ -61,6 +61,14 @@ impl OpaqueSender<CompositorMsg> for CompositorProxy {
|
||||||
|
|
||||||
impl CompositorProxy {
|
impl CompositorProxy {
|
||||||
pub fn send(&self, msg: CompositorMsg) {
|
pub fn send(&self, msg: CompositorMsg) {
|
||||||
|
self.route_msg(Ok(msg))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper method to route a deserialized IPC message to the receiver.
|
||||||
|
///
|
||||||
|
/// This method is a temporary solution, and will be removed when migrating
|
||||||
|
/// to `GenericChannel`.
|
||||||
|
pub fn route_msg(&self, msg: Result<CompositorMsg, ipc_channel::Error>) {
|
||||||
if let Err(err) = self.sender.send(msg) {
|
if let Err(err) = self.sender.send(msg) {
|
||||||
warn!("Failed to send response ({:?}).", err);
|
warn!("Failed to send response ({:?}).", err);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue