wayland: fix pump events's loop drop deadlock

This commit is contained in:
Kirill Chibisov
2025-05-17 13:23:01 +09:00
parent bd2b5cda8d
commit f7ac8127e3
2 changed files with 12 additions and 1 deletions

View File

@@ -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.

View File

@@ -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,
}