+}
+
+int waiter_poll(struct waitset *set)
+{
+ struct timeval now, timeout;
+ struct waiter *waiter, *tmp;
+ 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;
+ }
+
+ rc = poll(set->pollfds, set->n_io_waiters, timeout_ms);
+
+ if (rc < 0) {
+ if (errno == EINTR)
+ rc = 0;
+ goto out;
+ }
+
+ for (i = 0; i < set->n_io_waiters; i++) {
+ struct waiter *waiter = set->io_waiters[i];
+
+ if (!waiter->active)
+ continue;
+
+ if (!set->pollfds[i].revents)
+ continue;
+ rc = waiter->callback(waiter->arg);
+
+ if (rc)
+ waiter_remove(waiter);
+ }
+
+ if (set->n_time_waiters > 0)
+ gettimeofday(&now, NULL);
+
+ for (i = 0; i < set->n_time_waiters; i++) {
+ struct waiter *waiter = set->time_waiters[i];
+
+ if (!waiter->active)
+ continue;
+
+ if (timercmp(&waiter->timeout, &now, >))
+ continue;
+
+ waiter->callback(waiter->arg);
+
+ waiter_remove(waiter);
+ }
+
+ rc = 0;
+
+out:
+ /* free any waiters that have been removed */
+ list_for_each_entry_safe(&set->free_list, waiter, tmp, list)
+ talloc_free(waiter);
+ list_init(&set->free_list);