On 12 January 2016 at 04:31, Jonas Ådahl <[email protected]> wrote: > 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. > > Signed-off-by: Jonas Ådahl <[email protected]> > --- > src/wayland-client.c | 39 +++++++++++++++++++++++++++++---------- > 1 file changed, 29 insertions(+), 10 deletions(-) > > diff --git a/src/wayland-client.c b/src/wayland-client.c > index 8bf6124..f47e395 100644 > --- a/src/wayland-client.c > +++ b/src/wayland-client.c > @@ -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[2]; why 2? why an array at all? why not just struct pollfd pfd; pfd.fd = display->fd; pfd.events = events; do { poll(&pfd, 1, -1); } while (blabla); (i understand this was in the original as well and you're simply moving code around) > + > + 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) { > + if (wl_display_poll(display, POLLOUT) == -1) { > + wl_display_cancel_read(display); > + return -1; > + } > + } else { > + break; > + } > + } > + > /* 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; > } > -- > 2.4.3 > > _______________________________________________ > wayland-devel mailing list > [email protected] > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
