+ /* IO waiters: copy to io_waiters, populate pollfds */
+ for (i = i_io = 0; i < set->n_waiters; i++) {
+ struct waiter *waiter = set->waiters[i];
+
+ if (waiter->type != WAITER_IO)
+ continue;
+
+ set->pollfds[i_io].fd = waiter->fd;
+ set->pollfds[i_io].events = waiter->events;
+ set->io_waiters[i_io] = waiter;
+ i_io++;
+ }
+
+ /* time waiters: copy to time_waiters, calculate next expiry */
+ timerclear(&set->next_timeout);
+ for (i = i_time = 0; i < set->n_waiters; i++) {
+ struct waiter *waiter = set->waiters[i];
+
+ if (waiter->type != WAITER_TIME)
+ continue;
+
+ if (!timerisset(&set->next_timeout) ||
+ timercmp(&waiter->timeout,
+ &set->next_timeout, <))
+ set->next_timeout = waiter->timeout;
+
+ set->time_waiters[i_time] = waiter;
+ i_time++;
+ }
+}
+
+int waiter_poll(struct waitset *set)
+{
+ struct timeval now, timeout;
+ int timeout_ms;
+ int i, rc;
+
+ /* If the waiters have been updated, we need to update our
+ * consistent copy */
+ update_waiters(set);
+
+ if (timerisset(&set->next_timeout)) {
+ gettimeofday(&now, NULL);
+ timersub(&set->next_timeout, &now, &timeout);
+ timeout_ms = timeout.tv_sec * 1000 +
+ timeout.tv_usec / 1000;
+ if (timeout_ms < 0)
+ timeout_ms = 0;
+ } else {
+ timeout_ms = -1;