wayland: fix pump events's loop drop deadlock

This commit is contained in:
Kirill Chibisov 2025-05-17 13:23:01 +09:00 committed by GitHub
parent c846f67bcb
commit 59e3dda89f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 12 additions and 1 deletions

View file

@ -247,3 +247,4 @@ changelog entry.
- On macOS, fixed the scancode conversion for `IntlBackslash`.
- On macOS, fixed redundant `SurfaceResized` event at window creation.
- 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

@ -739,7 +739,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() {
@ -767,6 +767,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);
@ -802,4 +810,6 @@ enum PumpEventNotifierAction {
Monitor,
/// Pause monitoring.
Pause,
/// Shutdown the thread.
Shutdown,
}