mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-10-29 05:40:16 -04:00
client: Fully flush during blocking dispatch
wl_display_flush() may fail with EAGAIN which means that not all data waiting in the buffer has been flushed. We later block until there is data to read, which could mean that we block on input from the compositor without having sent out all data from the client. Avoid this by fully flushing the socket before starting to wait. This commit also changes the array length of the struct pollfd array from 2 to 1, as only one element was ever used. Signed-off-by: Jonas Ådahl <jadahl@gmail.com> Reviewed-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
parent
689fff36ca
commit
242617c316
1 changed files with 29 additions and 10 deletions
|
|
@ -1442,6 +1442,21 @@ wl_display_cancel_read(struct wl_display *display)
|
|||
pthread_mutex_unlock(&display->mutex);
|
||||
}
|
||||
|
||||
static int
|
||||
wl_display_poll(struct wl_display *display, short int events)
|
||||
{
|
||||
int ret;
|
||||
struct pollfd pfd[1];
|
||||
|
||||
pfd[0].fd = display->fd;
|
||||
pfd[0].events = events;
|
||||
do {
|
||||
ret = poll(pfd, 1, -1);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Dispatch events in an event queue
|
||||
*
|
||||
* \param display The display context object
|
||||
|
|
@ -1485,27 +1500,31 @@ WL_EXPORT int
|
|||
wl_display_dispatch_queue(struct wl_display *display,
|
||||
struct wl_event_queue *queue)
|
||||
{
|
||||
struct pollfd pfd[2];
|
||||
int ret;
|
||||
|
||||
if (wl_display_prepare_read_queue(display, queue) == -1)
|
||||
return wl_display_dispatch_queue_pending(display, queue);
|
||||
|
||||
while (true) {
|
||||
ret = wl_display_flush(display);
|
||||
|
||||
if (ret != -1 || errno != EAGAIN)
|
||||
break;
|
||||
|
||||
if (wl_display_poll(display, POLLOUT) == -1) {
|
||||
wl_display_cancel_read(display);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't stop if flushing hits an EPIPE; continue so we can read any
|
||||
* protocol error that may have triggered it. */
|
||||
ret = wl_display_flush(display);
|
||||
if (ret < 0 && errno != EAGAIN && errno != EPIPE) {
|
||||
if (ret < 0 && errno != EPIPE) {
|
||||
wl_display_cancel_read(display);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pfd[0].fd = display->fd;
|
||||
pfd[0].events = POLLIN;
|
||||
do {
|
||||
ret = poll(pfd, 1, -1);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
|
||||
if (ret == -1) {
|
||||
if (wl_display_poll(display, POLLIN) == -1) {
|
||||
wl_display_cancel_read(display);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue