+/*
+ * Fills the at least 'njbuses' structures of array 'fds' with data needed
+ * to poll the 'njbuses' buses pointed by 'jbuses'.
+ *
+ * Returns the count of 'fds' structures filled.
+ */
+int jbus_fill_pollfds(struct jbus **jbuses, int njbuses, struct pollfd *fds)
+{
+ int i, r;
+
+ for (r = i = 0; i < njbuses; i++) {
+ if (jbuses[i]->watchnr) {
+ fds[r].fd = jbuses[i]->watchfd;
+ fds[r].events = jbuses[i]->watchflags;
+ r++;
+ }
+ }
+ return r;
+}
+
+/*
+ * Dispatchs a maximum of 'maxcount' events received by poll in 'fds' for the
+ * 'njbuses' jbuses of the array 'jbuses'.
+ *
+ * Returns the count of event dispatched.
+ */
+int jbus_dispatch_pollfds(
+ struct jbus **jbuses,
+ int njbuses,
+ struct pollfd *fds,
+ int maxcount)
+{
+ int i, r, n;
+ DBusDispatchStatus sts;
+
+ for (r = n = i = 0; i < njbuses && n < maxcount; i++) {
+ if (jbuses[i]->watchnr && fds[r].fd == jbuses[i]->watchfd) {
+ if (fds[r].revents) {
+ dbus_connection_read_write(
+ jbuses[i]->connection, 0);
+ sts = dbus_connection_get_dispatch_status(
+ jbuses[i]->connection);
+ while (sts == DBUS_DISPATCH_DATA_REMAINS
+ && n < maxcount) {
+ sts = dbus_connection_dispatch(
+ jbuses[i]->connection);
+ n++;
+ }
+ }
+ r++;
+ }
+ }
+ return n;
+}
+
+/*
+ * Dispatches 'maxcount' of buffered data from the 'njbuses' jbuses of the
+ * array 'jbuses'.
+ *
+ * Returns the count of event dispatched.
+ */
+int jbus_dispatch_multiple(struct jbus **jbuses, int njbuses, int maxcount)
+{
+ int i, r;
+ DBusDispatchStatus sts;
+
+ for (i = r = 0; i < njbuses && r < maxcount; i++) {
+ dbus_connection_read_write(jbuses[i]->connection, 0);
+ sts = dbus_connection_get_dispatch_status(
+ jbuses[i]->connection);
+ while (sts == DBUS_DISPATCH_DATA_REMAINS && r < maxcount) {
+ sts = dbus_connection_dispatch(jbuses[i]->connection);
+ r++;
+ }
+ }
+ return r;
+}
+
+/*
+ * Polls during at most 'toms' milliseconds and dispatches 'maxcount'
+ * of events from the 'njbuses' jbuses of the array 'jbuses'.
+ *
+ * Returns the count of event dispatched or -1 in case of error.
+ */
+int jbus_read_write_dispatch_multiple(
+ struct jbus **jbuses,
+ int njbuses,
+ int toms,
+ int maxcount)
+{
+ int n, r, s;
+ struct pollfd *fds;
+
+ if (njbuses < 0 || njbuses > 100) {
+ errno = EINVAL;
+ return -1;
+ }
+ fds = alloca((unsigned)njbuses * sizeof *fds);
+ assert(fds != NULL);
+
+ r = jbus_dispatch_multiple(jbuses, njbuses, maxcount);
+ if (r)
+ return r;
+ n = jbus_fill_pollfds(jbuses, njbuses, fds);
+ for (;;) {
+ s = poll(fds, (nfds_t) n, toms);
+ if (s >= 0)
+ break;
+ if (errno != EINTR)
+ return r ? r : s;
+ toms = 0;
+ }
+ n = jbus_dispatch_pollfds(jbuses, njbuses, fds, maxcount - r);
+ return n >= 0 ? r + n : r ? r : n;
+}
+
+/*
+ * Polls during at most 'toms' milliseconds and dispatches
+ * the events from 'jbus'.
+ *
+ * Returns the count of event dispatched or -1 in case of error.
+ */