summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2013-10-15 15:15:31 +0200
committerHans de Goede <hdegoede@redhat.com>2013-11-20 13:21:28 +0100
commit359a273b36d810e0fda4117a3131116350db822b (patch)
tree0c2bd51b7034d764b646c02fabcd22a5711a3013
parent7b62a0a171ac0141a3d12237ab496c49cccd79df (diff)
downloadlibusb-359a273b36d810e0fda4117a3131116350db822b.tar.gz
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 <hdegoede@redhat.com>
-rw-r--r--libusb/io.c11
-rw-r--r--libusb/version_nano.h2
2 files changed, 12 insertions, 1 deletions
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