On 11/01/16 10:31 PM, Jonas Ådahl 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 > 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.
Is this because wl_connection_flush() uses sendmsg with MSG_DONTWAIT? Can we figure out a way to get "bool blocking" down to wl_connection_flush and avoid the poll thing entirely? Maybe have a wl_display_blocking_flush() or whatever... Wouldn't even need to be external API if only wl_display_dispatch_queue calls it... Thanks, Derek > 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]; > + > + 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; > } > _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
