+ }
+#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;
+
+ 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();
+ triggered = FALSE;
+ stopped = FALSE;
+
+ for (i = 0; i < session->sources->len; ++i) {
+ source = &g_array_index(session->sources, struct source, i);
+ if (source->triggered)
+ continue; /* already handled */
+
+ poll_object = source->poll_object;
+ fd = (int)poll_object;
+ revents = 0;
+
+ if (i < session->pollfds->len) {
+ pollfd = &g_array_index(session->pollfds, GPollFD, i);
+ fd = pollfd->fd;
+ if (ret > 0)
+ revents = pollfd->revents;
+ }
+ if (ret > 0 && revents == 0)
+ continue; /* skip timeouts if any I/O event occurred */
+
+ due = source->due;
+#ifdef HAVE_LIBUSB_1_0
+ if (source->is_usb && usb_due < due)
+ due = usb_due;
+#endif
+ if (revents == 0 && stop_time < due)
+ continue;
+ /*
+ * The source may be gone after the callback returns,
+ * so access any data now that needs accessing.
+ */
+ if (source->timeout >= 0)
+ source->due = stop_time + source->timeout;
+ source->triggered = TRUE;
+ triggered = TRUE;
+ /*
+ * Invoke the source's callback on an event or timeout.
+ */
+ if (!source->cb(fd, revents, source->cb_data))
+ _sr_session_source_remove(session, poll_object);