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>
(cherry picked from commit 785e59060c)
			
			
This commit is contained in:
		
							parent
							
								
									b8b10e2930
								
							
						
					
					
						commit
						0430d13c1e
					
				| 
						 | 
					@ -2904,9 +2904,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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1043,6 +1043,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");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static CARD32
 | 
					static CARD32
 | 
				
			||||||
add_client_fd(OsTimerPtr timer, CARD32 time, void *arg)
 | 
					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);
 | 
					    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;
 | 
				
			||||||
| 
						 | 
					@ -1281,9 +1287,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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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_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);
 | 
					Bool xwl_screen_init_cursor(struct xwl_screen *xwl_screen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct xwl_screen *xwl_screen_get(ScreenPtr screen);
 | 
					struct xwl_screen *xwl_screen_get(ScreenPtr screen);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue