From cf5bd72877546abdf15e47d0d7e25611bffaa1e3 Mon Sep 17 00:00:00 2001 From: roboomp Date: Fri, 7 Aug 2026 11:12:04 +0000 Subject: [PATCH] fix(computer): bounded portal close and closed leaked session Bounded the RemoteDesktop close in Libei::drop with CLOSE_TIMEOUT so an unresponsive xdg-desktop-portal cannot hang worker teardown past the surrounding close budget. Closed the portal session when ei::Context::new fails after Start/ConnectToEIS, the one init path that previously dropped the session without revoking the grant. Fixes #7884 --- .../src/desktop/linux/wayland/libei.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/crates/pi-natives/src/desktop/linux/wayland/libei.rs b/crates/pi-natives/src/desktop/linux/wayland/libei.rs index 4380e9bd3..8e317ece1 100644 --- a/crates/pi-natives/src/desktop/linux/wayland/libei.rs +++ b/crates/pi-natives/src/desktop/linux/wayland/libei.rs @@ -43,10 +43,18 @@ impl Drop for Libei { let Some(portal) = self.portal_session.take() else { return; }; - let _ = portal.runtime.block_on(portal.session.close()); + close_session(portal.runtime, &portal.session); } } +/// Closes a RemoteDesktop portal session, bounded by `CLOSE_TIMEOUT` so an +/// unresponsive `xdg-desktop-portal` cannot hang teardown indefinitely. +fn close_session(runtime: &tokio::runtime::Runtime, session: &RemoteDesktopSession) { + let _ = runtime.block_on(async { + tokio::time::timeout(crate::desktop::CLOSE_TIMEOUT, session.close()).await + }); +} + impl Libei { pub(super) fn new() -> CoreResult { let (context, portal_session) = match ei::Context::connect_to_env() { @@ -114,8 +122,13 @@ impl Libei { } }) .map_err(DesktopError::permission_denied)?; - let context = ei::Context::new(UnixStream::from(fd)) - .map_err(|err| DesktopError::input_failed(format!("libei portal socket: {err}")))?; + let context = match ei::Context::new(UnixStream::from(fd)) { + Ok(context) => context, + Err(err) => { + close_session(runtime, &session); + return Err(DesktopError::input_failed(format!("libei portal socket: {err}"))); + }, + }; Ok((context, PortalSession { runtime, session })) }