From 0430d13c1ed8ddbb1d5a57d7e507771f8079d9af Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Fri, 24 Apr 2020 17:45:49 +0200 Subject: [PATCH] xwayland: Fix infinite loop at startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mutter recently added headless tests, and when running those tests the Wayland compositor runs for a very short time. Xwayland is spawned by the Wayland compositor and upon startup will query the various Wayland protocol supported by the compositor. To do so, it will do a roundtrip to the Wayland server waiting for events it expects. If the Wayland compositor terminates before Xwayland has got the replies it expects, it will loop indefinitely calling `wl_display_roundtrip()` continuously. To avoid that issue, add a new `xwl_screen_roundtrip()` that checks for the returned value from `wl_display_roundtrip()` and fails if it is negative. Signed-off-by: Olivier Fourdan Reviewed-by: Roman Gilg Reviewed-by: Jonas Ã…dahl (cherry picked from commit 785e59060c00129e47da6c0877604a56d7e0e32f) --- hw/xwayland/xwayland-input.c | 4 +--- hw/xwayland/xwayland.c | 26 +++++++++++++++----------- hw/xwayland/xwayland.h | 2 ++ 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index fa46ac3e7..ba2febc1d 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -2904,9 +2904,7 @@ InitInput(int argc, char *argv[]) xwl_screen->XYToWindow = pScreen->XYToWindow; pScreen->XYToWindow = xwl_xy_to_window; - wl_display_roundtrip(xwl_screen->display); - while (xwl_screen->expecting_event) - wl_display_roundtrip(xwl_screen->display); + xwl_screen_roundtrip(xwl_screen); } void diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c index ed9f2e3c2..44d1bb4da 100644 --- a/hw/xwayland/xwayland.c +++ b/hw/xwayland/xwayland.c @@ -1043,6 +1043,19 @@ xwl_sync_events (struct xwl_screen *xwl_screen) xwl_read_events (xwl_screen); } +void +xwl_screen_roundtrip(struct xwl_screen *xwl_screen) +{ + int ret; + + ret = wl_display_roundtrip(xwl_screen->display); + while (ret >= 0 && xwl_screen->expecting_event) + ret = wl_display_roundtrip(xwl_screen->display); + + if (ret < 0) + xwl_give_up("could not connect to wayland server\n"); +} + static CARD32 add_client_fd(OsTimerPtr timer, CARD32 time, void *arg) { @@ -1182,14 +1195,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) xwl_screen->registry = wl_display_get_registry(xwl_screen->display); wl_registry_add_listener(xwl_screen->registry, ®istry_listener, xwl_screen); - ret = wl_display_roundtrip(xwl_screen->display); - if (ret == -1) { - ErrorF("could not connect to wayland server\n"); - return FALSE; - } - - while (xwl_screen->expecting_event > 0) - wl_display_roundtrip(xwl_screen->display); + xwl_screen_roundtrip(xwl_screen); bpc = xwl_screen->depth / 3; green_bpc = xwl_screen->depth - 2 * bpc; @@ -1281,9 +1287,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) AddCallback(&PropertyStateCallback, xwl_property_callback, pScreen); - wl_display_roundtrip(xwl_screen->display); - while (xwl_screen->expecting_event) - wl_display_roundtrip(xwl_screen->display); + xwl_screen_roundtrip(xwl_screen); return ret; } diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index daa719209..bc5836ec4 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -381,6 +381,8 @@ void xwl_window_create_frame_callback(struct xwl_window *xwl_window); void xwl_sync_events (struct xwl_screen *xwl_screen); +void xwl_screen_roundtrip (struct xwl_screen *xwl_screen); + Bool xwl_screen_init_cursor(struct xwl_screen *xwl_screen); struct xwl_screen *xwl_screen_get(ScreenPtr screen);