+ int fd;
+ int revents;
+ gboolean triggered, stopped;
+ struct source *source;
+ GPollFD *pollfd;
+ gintptr poll_object;
+#if HAVE_LIBUSB_1_0 && !defined(G_OS_WIN32)
+ int64_t usb_timeout;
+ int64_t usb_due;
+ struct timeval tv;
+#endif
+ if (session->sources->len == 0) {
+ sr_session_check_aborted(session);
+ return SR_OK;
+ }
+ start_time = g_get_monotonic_time();
+ min_due = INT64_MAX;
+
+ for (i = 0; i < session->sources->len; ++i) {
+ source = &g_array_index(session->sources, struct source, i);
+ if (source->due < min_due)
+ min_due = source->due;
+ source->triggered = FALSE;
+ }
+#if HAVE_LIBUSB_1_0 && !defined(G_OS_WIN32)
+ usb_due = INT64_MAX;
+ if (session->ctx->usb_source_present) {
+ 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 = (int64_t)tv.tv_sec * G_USEC_PER_SEC
+ + tv.tv_usec;
+ usb_due = start_time + usb_timeout;
+ if (usb_due < min_due)
+ min_due = usb_due;
+
+ sr_spew("poll: next USB timeout %g ms",
+ 1e-3 * usb_timeout);
+ }
+ }
+#endif
+ if (min_due == INT64_MAX)
+ timeout_ms = -1;
+ else if (min_due > start_time)
+ timeout_ms = MIN((min_due - start_time + 999) / 1000, INT_MAX);
+ else
+ timeout_ms = 0;
+
+ sr_spew("poll enter: %u sources, %u fds, %d ms timeout",
+ session->sources->len, session->pollfds->len, timeout_ms);
+
+ ret = g_poll((GPollFD *)session->pollfds->data,
+ session->pollfds->len, timeout_ms);
+#ifdef G_OS_UNIX
+ if (ret < 0 && errno != EINTR) {
+ sr_err("Error in poll: %s", g_strerror(errno));
+ return SR_ERR;
+ }
+#else
+ if (ret < 0) {
+ sr_err("Error in poll: %d", ret);
+ return SR_ERR;
+ }
+#endif
+ stop_time = g_get_monotonic_time();