xwayland: Fix infinite loop at startup
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 <ofourdan@redhat.com> Reviewed-by: Roman Gilg <subdiff@gmail.com> Reviewed-by: Jonas Ådahl <jadahl@gmail.com>
This commit is contained in:
parent
2fe13a1f44
commit
785e59060c
|
@ -2915,9 +2915,7 @@ InitInput(int argc, char *argv[])
|
||||||
xwl_screen->XYToWindow = pScreen->XYToWindow;
|
xwl_screen->XYToWindow = pScreen->XYToWindow;
|
||||||
pScreen->XYToWindow = xwl_xy_to_window;
|
pScreen->XYToWindow = xwl_xy_to_window;
|
||||||
|
|
||||||
wl_display_roundtrip(xwl_screen->display);
|
xwl_screen_roundtrip(xwl_screen);
|
||||||
while (xwl_screen->expecting_event)
|
|
||||||
wl_display_roundtrip(xwl_screen->display);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -489,6 +489,19 @@ xwl_sync_events (struct xwl_screen *xwl_screen)
|
||||||
xwl_read_events (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");
|
||||||
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
|
xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -572,14 +585,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
|
||||||
xwl_screen->registry = wl_display_get_registry(xwl_screen->display);
|
xwl_screen->registry = wl_display_get_registry(xwl_screen->display);
|
||||||
wl_registry_add_listener(xwl_screen->registry,
|
wl_registry_add_listener(xwl_screen->registry,
|
||||||
®istry_listener, xwl_screen);
|
®istry_listener, xwl_screen);
|
||||||
ret = wl_display_roundtrip(xwl_screen->display);
|
xwl_screen_roundtrip(xwl_screen);
|
||||||
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);
|
|
||||||
|
|
||||||
bpc = xwl_screen->depth / 3;
|
bpc = xwl_screen->depth / 3;
|
||||||
green_bpc = xwl_screen->depth - 2 * bpc;
|
green_bpc = xwl_screen->depth - 2 * bpc;
|
||||||
|
@ -678,9 +684,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
|
||||||
|
|
||||||
AddCallback(&PropertyStateCallback, xwl_property_callback, pScreen);
|
AddCallback(&PropertyStateCallback, xwl_property_callback, pScreen);
|
||||||
|
|
||||||
wl_display_roundtrip(xwl_screen->display);
|
xwl_screen_roundtrip(xwl_screen);
|
||||||
while (xwl_screen->expecting_event)
|
|
||||||
wl_display_roundtrip(xwl_screen->display);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,7 @@ struct xwl_output *xwl_screen_get_first_output(struct xwl_screen *xwl_screen);
|
||||||
Bool xwl_close_screen(ScreenPtr screen);
|
Bool xwl_close_screen(ScreenPtr screen);
|
||||||
Bool xwl_screen_init(ScreenPtr pScreen, int argc, char **argv);
|
Bool xwl_screen_init(ScreenPtr pScreen, int argc, char **argv);
|
||||||
void xwl_sync_events (struct xwl_screen *xwl_screen);
|
void xwl_sync_events (struct xwl_screen *xwl_screen);
|
||||||
|
void xwl_screen_roundtrip (struct xwl_screen *xwl_screen);
|
||||||
void xwl_surface_damage(struct xwl_screen *xwl_screen,
|
void xwl_surface_damage(struct xwl_screen *xwl_screen,
|
||||||
struct wl_surface *surface,
|
struct wl_surface *surface,
|
||||||
int32_t x, int32_t y, int32_t width, int32_t height);
|
int32_t x, int32_t y, int32_t width, int32_t height);
|
||||||
|
|
Loading…
Reference in New Issue