From f7ac8127e38b54f71033035acbf90be8a962d1c5 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Sat, 17 May 2025 13:23:01 +0900 Subject: [PATCH] wayland: fix pump events's loop drop deadlock --- src/changelog/unreleased.md | 1 + src/platform_impl/linux/wayland/event_loop/mod.rs | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/changelog/unreleased.md b/src/changelog/unreleased.md index 5a50389ae..409485329 100644 --- a/src/changelog/unreleased.md +++ b/src/changelog/unreleased.md @@ -43,3 +43,4 @@ changelog entry. ### Fixed - On Windows, fixed crash in should_apps_use_dark_mode() for Windows versions < 17763. +- On Wayland, fixed `pump_events` driven loop deadlocking when loop was not drained before exit. diff --git a/src/platform_impl/linux/wayland/event_loop/mod.rs b/src/platform_impl/linux/wayland/event_loop/mod.rs index 99b282cb4..fef13f455 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -734,7 +734,7 @@ impl Drop for PumpEventNotifier { if let Some(worker_waker) = self.worker_waker.as_ref() { let _ = rustix::io::write(worker_waker.as_fd(), &[0u8]); } - *self.control.0.lock().unwrap() = PumpEventNotifierAction::Monitor; + *self.control.0.lock().unwrap() = PumpEventNotifierAction::Shutdown; self.control.1.notify_one(); if let Some(handle) = self.handle.take() { @@ -762,6 +762,14 @@ impl PumpEventNotifier { while *wait == PumpEventNotifierAction::Pause { wait = cvar.wait(wait).unwrap(); } + + // Exit the loop when we're asked to. Given that we poll + // only once we can take the `prepare_read`, but in some cases + // it could be not possible, we may block on `join`. + if *wait == PumpEventNotifierAction::Shutdown { + break 'outer; + } + // Wake-up the main loop and put this one back to sleep. *wait = PumpEventNotifierAction::Pause; drop(wait); @@ -797,4 +805,6 @@ enum PumpEventNotifierAction { Monitor, /// Pause monitoring. Pause, + /// Shutdown the thread. + Shutdown, }