mirror of
https://github.com/marcoallegretti/WEFT_OS.git
synced 2026-03-27 01:13:09 +00:00
fix(compositor): replace panic-prone unwraps with explicit error handling in winit and DRM backends
- winit backend: client insertion and dispatch_clients failures now log and continue instead of unwinding the event loop - winit backend: bind/render/submit failures in the redraw handler skip the frame and log a warning; the compositor stays running - DRM backend: same client insertion and dispatch_clients treatment - DRM device_added: use .context()? instead of unwrap() when inserting the new device entry after the drm field is known to be initialised - DRM render_output: use guard-return instead of unwrap() to access drm state that was already verified non-None lines above - compositor state: duplicate layer surface mapping from a misbehaving client logs a warning and returns instead of panicking
This commit is contained in:
parent
67f54c39be
commit
b82345d24e
3 changed files with 49 additions and 24 deletions
|
|
@ -137,10 +137,12 @@ pub fn run() -> anyhow::Result<()> {
|
||||||
|
|
||||||
loop_handle
|
loop_handle
|
||||||
.insert_source(listening_socket, |stream, _, state| {
|
.insert_source(listening_socket, |stream, _, state| {
|
||||||
state
|
if let Err(e) = state
|
||||||
.display_handle
|
.display_handle
|
||||||
.insert_client(stream, Arc::new(WeftClientState::default()))
|
.insert_client(stream, Arc::new(WeftClientState::default()))
|
||||||
.unwrap();
|
{
|
||||||
|
tracing::warn!(?e, "failed to insert Wayland client");
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.map_err(|e| anyhow::anyhow!("socket source: {e}"))?;
|
.map_err(|e| anyhow::anyhow!("socket source: {e}"))?;
|
||||||
|
|
||||||
|
|
@ -150,7 +152,9 @@ pub fn run() -> anyhow::Result<()> {
|
||||||
|_, display, state| {
|
|_, display, state| {
|
||||||
// Safety: Display is owned by this Generic source and outlives the event loop.
|
// Safety: Display is owned by this Generic source and outlives the event loop.
|
||||||
unsafe {
|
unsafe {
|
||||||
display.get_mut().dispatch_clients(state).unwrap();
|
if let Err(e) = display.get_mut().dispatch_clients(state) {
|
||||||
|
tracing::warn!(?e, "Wayland dispatch error");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(PostAction::Continue)
|
Ok(PostAction::Continue)
|
||||||
},
|
},
|
||||||
|
|
@ -375,16 +379,21 @@ fn device_added(state: &mut WeftCompositorState, node: DrmNode, path: &Path) ->
|
||||||
)
|
)
|
||||||
.map_err(|e| anyhow::anyhow!("DRM notifier: {e}"))?;
|
.map_err(|e| anyhow::anyhow!("DRM notifier: {e}"))?;
|
||||||
|
|
||||||
state.drm.as_mut().unwrap().devices.insert(
|
state
|
||||||
node,
|
.drm
|
||||||
WeftDrmDevice {
|
.as_mut()
|
||||||
drm_output_manager,
|
.context("DRM data missing after initialization")?
|
||||||
drm_scanner: DrmScanner::new(),
|
.devices
|
||||||
surfaces: HashMap::new(),
|
.insert(
|
||||||
render_node,
|
node,
|
||||||
registration_token,
|
WeftDrmDevice {
|
||||||
},
|
drm_output_manager,
|
||||||
);
|
drm_scanner: DrmScanner::new(),
|
||||||
|
surfaces: HashMap::new(),
|
||||||
|
render_node,
|
||||||
|
registration_token,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
device_changed(state, node);
|
device_changed(state, node);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -604,7 +613,7 @@ fn render_output(state: &mut WeftCompositorState, node: DrmNode, crtc: crtc::Han
|
||||||
};
|
};
|
||||||
|
|
||||||
let render_node = {
|
let render_node = {
|
||||||
let d = state.drm.as_ref().unwrap();
|
let Some(d) = state.drm.as_ref() else { return };
|
||||||
d.devices
|
d.devices
|
||||||
.get(&node)
|
.get(&node)
|
||||||
.and_then(|d| d.render_node)
|
.and_then(|d| d.render_node)
|
||||||
|
|
|
||||||
|
|
@ -63,10 +63,12 @@ pub fn run() -> anyhow::Result<()> {
|
||||||
|
|
||||||
loop_handle
|
loop_handle
|
||||||
.insert_source(listening_socket, |client_stream, _, state| {
|
.insert_source(listening_socket, |client_stream, _, state| {
|
||||||
state
|
if let Err(e) = state
|
||||||
.display_handle
|
.display_handle
|
||||||
.insert_client(client_stream, Arc::new(WeftClientState::default()))
|
.insert_client(client_stream, Arc::new(WeftClientState::default()))
|
||||||
.unwrap();
|
{
|
||||||
|
tracing::warn!(?e, "failed to insert Wayland client");
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.map_err(|e| anyhow::anyhow!("socket source insertion failed: {e}"))?;
|
.map_err(|e| anyhow::anyhow!("socket source insertion failed: {e}"))?;
|
||||||
|
|
||||||
|
|
@ -78,7 +80,9 @@ pub fn run() -> anyhow::Result<()> {
|
||||||
// Safety: the display is owned by this Generic source and is never dropped
|
// Safety: the display is owned by this Generic source and is never dropped
|
||||||
// while the event loop runs.
|
// while the event loop runs.
|
||||||
unsafe {
|
unsafe {
|
||||||
display.get_mut().dispatch_clients(state).unwrap();
|
if let Err(e) = display.get_mut().dispatch_clients(state) {
|
||||||
|
tracing::warn!(?e, "Wayland dispatch error");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(PostAction::Continue)
|
Ok(PostAction::Continue)
|
||||||
},
|
},
|
||||||
|
|
@ -129,9 +133,8 @@ pub fn run() -> anyhow::Result<()> {
|
||||||
let size = backend.window_size();
|
let size = backend.window_size();
|
||||||
let full_damage = Rectangle::from_size(size);
|
let full_damage = Rectangle::from_size(size);
|
||||||
|
|
||||||
{
|
let render_ok = match backend.bind() {
|
||||||
let (renderer, mut framebuffer) = backend.bind().unwrap();
|
Ok((renderer, mut framebuffer)) => smithay::desktop::space::render_output::<
|
||||||
smithay::desktop::space::render_output::<
|
|
||||||
_,
|
_,
|
||||||
WaylandSurfaceRenderElement<GlesRenderer>,
|
WaylandSurfaceRenderElement<GlesRenderer>,
|
||||||
_,
|
_,
|
||||||
|
|
@ -147,9 +150,18 @@ pub fn run() -> anyhow::Result<()> {
|
||||||
&mut damage_tracker,
|
&mut damage_tracker,
|
||||||
[0.1_f32, 0.1, 0.1, 1.0],
|
[0.1_f32, 0.1, 0.1, 1.0],
|
||||||
)
|
)
|
||||||
.unwrap();
|
.map_err(|e| tracing::warn!(?e, "render_output failed"))
|
||||||
|
.is_ok(),
|
||||||
|
Err(e) => {
|
||||||
|
tracing::warn!(?e, "backend bind failed");
|
||||||
|
false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if render_ok {
|
||||||
|
if let Err(e) = backend.submit(Some(&[full_damage])) {
|
||||||
|
tracing::warn!(?e, "backend submit failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
backend.submit(Some(&[full_damage])).unwrap();
|
|
||||||
|
|
||||||
state.space.elements().for_each(|window| {
|
state.space.elements().for_each(|window| {
|
||||||
window.send_frame(
|
window.send_frame(
|
||||||
|
|
|
||||||
|
|
@ -294,9 +294,13 @@ impl WlrLayerShellHandler for WeftCompositorState {
|
||||||
) {
|
) {
|
||||||
let desktop_surface = DesktopLayerSurface::new(surface, namespace);
|
let desktop_surface = DesktopLayerSurface::new(surface, namespace);
|
||||||
if let Some(output) = self.space.outputs().next().cloned() {
|
if let Some(output) = self.space.outputs().next().cloned() {
|
||||||
layer_map_for_output(&output)
|
if layer_map_for_output(&output)
|
||||||
.map_layer(&desktop_surface)
|
.map_layer(&desktop_surface)
|
||||||
.expect("layer surface must not already be mapped");
|
.is_err()
|
||||||
|
{
|
||||||
|
tracing::warn!("received duplicate layer surface mapping; ignoring");
|
||||||
|
return;
|
||||||
|
}
|
||||||
layer_map_for_output(&output).arrange();
|
layer_map_for_output(&output).arrange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue