From 4974585d0436be36a2b37b75dbbcffbdec5238b4 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Wed, 18 Mar 2015 19:50:14 +0100 Subject: [PATCH] wayland: Handle disconnect properly Merge code for PollEvents and WaitEvents, and handle disconnect properly. --- src/wl_window.c | 73 ++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index bb2da473..3492aed5 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -114,6 +114,43 @@ createTmpfileCloexec(char* tmpname) return fd; } +static void +handleEvents(int timeout) +{ + struct wl_display* display = _glfw.wl.display; + struct pollfd fds[] = { + { wl_display_get_fd(display), POLLIN }, + }; + + while (wl_display_prepare_read(display) != 0) + wl_display_dispatch_pending(display); + + // If an error different from EAGAIN happens, we have likely been + // disconnected from the Wayland session, try to handle that the best we + // can. + if (wl_display_flush(display) < 0 && errno != EAGAIN) + { + _GLFWwindow* window = _glfw.windowListHead; + while (window) + { + _glfwInputWindowCloseRequest(window); + window = window->next; + } + wl_display_cancel_read(display); + return; + } + + if (poll(fds, 1, timeout) > 0) + { + wl_display_read_events(display); + wl_display_dispatch_pending(display); + } + else + { + wl_display_cancel_read(display); + } +} + /* * Create a new, unique, anonymous file of the given size, and * return the file descriptor for it. The file descriptor is set @@ -327,44 +364,12 @@ int _glfwPlatformWindowVisible(_GLFWwindow* window) void _glfwPlatformPollEvents(void) { - struct wl_display* display = _glfw.wl.display; - struct pollfd fds[] = { - { wl_display_get_fd(display), POLLIN }, - }; - - while (wl_display_prepare_read(display) != 0) - wl_display_dispatch_pending(display); - wl_display_flush(display); - if (poll(fds, 1, 0) > 0) - { - wl_display_read_events(display); - wl_display_dispatch_pending(display); - } - else - { - wl_display_cancel_read(display); - } + handleEvents(0); } void _glfwPlatformWaitEvents(void) { - struct wl_display* display = _glfw.wl.display; - struct pollfd fds[] = { - { wl_display_get_fd(display), POLLIN }, - }; - - while (wl_display_prepare_read(display) != 0) - wl_display_dispatch_pending(display); - wl_display_flush(display); - if (poll(fds, 1, -1) > 0) - { - wl_display_read_events(display); - wl_display_dispatch_pending(display); - } - else - { - wl_display_cancel_read(display); - } + handleEvents(-1); } void _glfwPlatformPostEmptyEvent(void)