diff options
author | Dudemanguy <random342@airmail.cc> | 2020-07-29 10:05:07 -0500 |
---|---|---|
committer | Dudemanguy <random342@airmail.cc> | 2020-07-29 17:45:42 +0000 |
commit | 36951ab6a7f71627b67646a1114d01bf685903e2 (patch) | |
tree | 0a1039795d6d212d9fd08af82afe2ab9aecf0b73 /video/out | |
parent | 6e3d4aa94b170fa6de1bdda32d799cef8648167d (diff) | |
download | mpv-36951ab6a7f71627b67646a1114d01bf685903e2.tar.bz2 mpv-36951ab6a7f71627b67646a1114d01bf685903e2.tar.xz |
wayland: fix a potential race in wait_events
The read of the wayland display fd in vo_wayland_wait_events was
incorrect and technically vulnerable to race conditions. The correct
usage as per the client api is to use wl_display_prepare_read as well as
wl_display_read_events.
Diffstat (limited to 'video/out')
-rw-r--r-- | video/out/wayland_common.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index efb1a48ef5..021ac5037a 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -1660,7 +1660,6 @@ void vo_wayland_wait_frame(struct vo_wayland_state *wl) void vo_wayland_wait_events(struct vo *vo, int64_t until_time_us) { struct vo_wayland_state *wl = vo->wl; - struct wl_display *display = wl->display; if (wl->display_fd == -1) return; @@ -1673,20 +1672,24 @@ void vo_wayland_wait_events(struct vo *vo, int64_t until_time_us) int64_t wait_us = until_time_us - mp_time_us(); int timeout_ms = MPCLAMP((wait_us + 999) / 1000, 0, 10000); - wl_display_dispatch_pending(display); - wl_display_flush(display); + while (wl_display_prepare_read(wl->display) != 0) + wl_display_dispatch_pending(wl->display); + wl_display_flush(wl->display); poll(fds, 2, timeout_ms); if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { MP_FATAL(wl, "Error occurred on the display fd, closing\n"); + wl_display_cancel_read(wl->display); close(wl->display_fd); wl->display_fd = -1; mp_input_put_key(vo->input_ctx, MP_KEY_CLOSE_WIN); + } else { + wl_display_read_events(wl->display); } if (fds[0].revents & POLLIN) - wl_display_dispatch(display); + wl_display_dispatch(wl->display); if (fds[1].revents & POLLIN) mp_flush_wakeup_pipe(wl->wakeup_pipe[0]); |