diff --git a/wayland-backend/CHANGELOG.md b/wayland-backend/CHANGELOG.md index 433ada7baa6..2239228d8b6 100644 --- a/wayland-backend/CHANGELOG.md +++ b/wayland-backend/CHANGELOG.md @@ -6,6 +6,10 @@ - `Backend::manage_object` for handling foreign proxies with the sys backend +#### Bugfixes + +- backend/rs: server: Fixed potential deadlock caused by dead clients + ## 0.3.4 -- 2024-05-30 #### Additions diff --git a/wayland-backend/src/rs/server_impl/common_poll.rs b/wayland-backend/src/rs/server_impl/common_poll.rs index d459d8076ce..7df83ecabe5 100644 --- a/wayland-backend/src/rs/server_impl/common_poll.rs +++ b/wayland-backend/src/rs/server_impl/common_poll.rs @@ -160,7 +160,37 @@ impl InnerBackend { return Err(e); } } - Err(e) => return Err(e), + Err(e) => { + #[cfg(any(target_os = "linux", target_os = "android"))] + { + epoll::delete(&state.poll_fd, client)?; + } + + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "macos" + ))] + { + use rustix::event::kqueue::*; + use std::os::unix::io::{AsFd, AsRawFd}; + + let evt = Event::new( + EventFilter::Read(client.as_fd().as_raw_fd()), + EventFlags::DELETE, + client_id.as_u64() as isize, + ); + + let mut events = Vec::new(); + unsafe { + kevent(&state.poll_fd, &[evt], &mut events, None) + .map(|_| ())?; + } + } + return Err(e); + } }; dispatched += 1; if same_interface(object.interface, &WL_DISPLAY_INTERFACE) {