wayland: prevent hang when terminating due to broken Wayland connection

If the call to fdm_wayl() with EPOLLHUP was followed by calls to
wayl_roundtrip(), foot would hang.

The reason for this is that the EPOLLHUP handler in fdm_wayl() would
call wl_display_cancel_read().

wayl_roundtrip() also calls wl_display_cancel_read() (since we
normally have called wl_display_prepare_read()), before calling
wl_display_roundtrip().

When calling wl_display_cancel_read() two times in a row, without a
wl_display_prepare_read() in between, wl_display_roundtrip() hangs.

Fix by not calling wl_display_cancel_read() in fdm_wayl(). This
ensures our invariant holds: wl_display_prepare_read() is *always* in
effect outside of fdm_wayl().

Closes #651
This commit is contained in:
Daniel Eklöf 2021-07-24 20:31:14 +02:00
parent 51250c64cc
commit bcd28311f4
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 11 additions and 1 deletions

View file

@ -48,6 +48,8 @@
* Crash in scrollback search mode when selection has been canceled due
to terminal content updates
(https://codeberg.org/dnkl/foot/issues/644).
* Foot process not terminating when the Wayland connection is broken
(https://codeberg.org/dnkl/foot/issues/651).
### Security

View file

@ -1163,7 +1163,15 @@ fdm_wayl(struct fdm *fdm, int fd, int events, void *data)
if (events & EPOLLHUP) {
LOG_WARN("disconnected from Wayland");
wl_display_cancel_read(wayl->display);
/*
* Do *not* call wl_display_cancel_read() here.
*
* Doing so causes later calls to wayl_roundtrip() (called
* from term_destroy() -> wayl_win_destroy()) to hang
* indefinitely.
*
* https://codeberg.org/dnkl/foot/issues/651
*/
return false;
}