From bb5f61105bac2d7826416472e2168d8f59300aea Mon Sep 17 00:00:00 2001 From: Martin Ling Date: Wed, 25 Mar 2015 05:16:06 +0000 Subject: [PATCH] Call libusb_get_next_timeout() to get minimum timeout for g_poll(). We should have been doing this all along, but we get away with it on Linux where libusb can do everything with fds, and we get away with it for many drivers that have a short timeout on their events. On Windows though, handling this correctly is essential. Fixes bug #343. --- src/session.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/session.c b/src/session.c index 276c5d17..0780a27a 100644 --- a/src/session.c +++ b/src/session.c @@ -379,10 +379,27 @@ SR_API int sr_session_trigger_set(struct sr_session *session, struct sr_trigger static int sr_session_iteration(struct sr_session *session, gboolean block) { unsigned int i; - int ret; + int ret, timeout; +#ifdef HAVE_LIBUSB_1_0 + int usb_timeout; + struct timeval tv; +#endif - ret = g_poll(session->pollfds, session->num_sources, - block ? session->source_timeout : 0); + timeout = block ? 0 : session->source_timeout; + +#ifdef HAVE_LIBUSB_1_0 + ret = libusb_get_next_timeout(session->ctx->libusb_ctx, &tv); + if (ret < 0) { + sr_err("Error getting libusb timeout: %s", + libusb_error_name(ret)); + return SR_ERR; + } else if (ret == 1) { + usb_timeout = tv.tv_sec * 1000 + tv.tv_usec / 1000; + timeout = MIN(timeout, usb_timeout); + } +#endif + + ret = g_poll(session->pollfds, session->num_sources, timeout); for (i = 0; i < session->num_sources; i++) { if (session->pollfds[i].revents > 0 || (ret == 0 && session->source_timeout == session->sources[i].timeout)) {