From 359a273b36d810e0fda4117a3131116350db822b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 15 Oct 2013 15:15:31 +0200 Subject: [PATCH] io: Ensure all pending events are consumed in one libusb_handle_events call Before this patch if ie multiple hot-plug events were pending, multiple handle_events calls would be necessary to handle them all, this patch changes handle_events so that the poll is re-done to check for more events if there was activity on any of the special fds. Signed-off-by: Hans de Goede --- libusb/io.c | 11 +++++++++++ libusb/version_nano.h | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/libusb/io.c b/libusb/io.c index 4f22963..a2c3dda 100644 --- a/libusb/io.c +++ b/libusb/io.c @@ -1930,6 +1930,7 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv) struct pollfd *fds = NULL; int i = -1; int timeout_ms; + int special_event; usbi_mutex_lock(&ctx->pollfds_lock); list_for_each_entry(ipollfd, &ctx->pollfds, list, struct usbi_pollfd) @@ -1959,6 +1960,7 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv) if (tv->tv_usec % 1000) timeout_ms++; +redo_poll: usbi_dbg("poll() %d fds with timeout in %dms", nfds, timeout_ms); r = usbi_poll(fds, nfds, timeout_ms); usbi_dbg("poll() returned %d", r); @@ -1974,6 +1976,8 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv) return LIBUSB_ERROR_IO; } + special_event = 0; + /* fd[0] is always the ctrl pipe */ if (fds[0].revents) { /* another thread wanted to interrupt event handling, and it succeeded! @@ -1997,6 +2001,7 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv) ssize_t ret; usbi_dbg("caught a fish on the hotplug pipe"); + special_event = 1; /* read the message from the hotplug thread */ ret = usbi_read(ctx->hotplug_pipe[0], &message, sizeof (message)); @@ -2024,6 +2029,7 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv) /* timerfd indicates that a timeout has expired */ int ret; usbi_dbg("timerfd triggered"); + special_event = 1; ret = handle_timerfd_trigger(ctx); if (ret < 0) { @@ -2048,6 +2054,11 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv) usbi_err(ctx, "backend handle_events failed with error %d", r); handled: + if (r == 0 && special_event) { + timeout_ms = 0; + goto redo_poll; + } + free(fds); return r; } diff --git a/libusb/version_nano.h b/libusb/version_nano.h index 1fc3694..d5afb48 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 10847 +#define LIBUSB_NANO 10848 -- 2.11.4.GIT