7 #include <talloc/talloc.h>
20 struct waiter **waiters;
24 /* These are kept consistent over each call to waiter_poll, as
25 * set->waiters may be updated (by waiters' callbacks calling
26 * waiter_register or waiter_remove) during iteration. */
27 struct pollfd *pollfds;
28 struct waiter **cur_waiters;
32 struct waitset *waitset_create(void *ctx)
34 struct waitset *set = talloc_zero(ctx, struct waitset);
38 void waitset_destroy(struct waitset *set)
43 struct waiter *waiter_register(struct waitset *set, int fd, int events,
44 waiter_cb callback, void *arg)
46 struct waiter **waiters, *waiter;
48 waiter = talloc(set->waiters, struct waiter);
52 waiters = talloc_realloc(set, set->waiters,
53 struct waiter *, set->n_waiters + 1);
60 set->waiters_changed = true;
61 set->waiters = waiters;
64 set->waiters[set->n_waiters - 1] = waiter;
68 waiter->events = events;
69 waiter->callback = callback;
75 void waiter_remove(struct waiter *waiter)
77 struct waitset *set = waiter->set;
80 for (i = 0; i < set->n_waiters; i++)
81 if (set->waiters[i] == waiter)
84 assert(i < set->n_waiters);
87 memmove(&set->waiters[i], &set->waiters[i+1],
88 (set->n_waiters - i) * sizeof(set->waiters[0]));
90 set->waiters = talloc_realloc(set->waiters, set->waiters,
91 struct waiter *, set->n_waiters);
92 set->waiters_changed = true;
97 int waiter_poll(struct waitset *set)
101 /* If the waiters have been updated, we need to update our
103 if (set->waiters_changed) {
105 /* We need to reallocate if the count has changes */
106 if (set->cur_n_waiters != set->n_waiters) {
107 set->cur_waiters = talloc_realloc(set, set->cur_waiters,
108 struct waiter *, set->n_waiters);
109 set->pollfds = talloc_realloc(set, set->pollfds,
110 struct pollfd, set->n_waiters);
111 set->cur_n_waiters = set->n_waiters;
114 /* Populate cur_waiters and pollfds from ->waiters data */
115 for (i = 0; i < set->n_waiters; i++) {
116 set->pollfds[i].fd = set->waiters[i]->fd;
117 set->pollfds[i].events = set->waiters[i]->events;
118 set->pollfds[i].revents = 0;
119 set->cur_waiters[i] = set->waiters[i];
122 set->waiters_changed = false;
125 rc = poll(set->pollfds, set->cur_n_waiters, -1);
130 for (i = 0; i < set->cur_n_waiters; i++) {
131 if (set->pollfds[i].revents) {
132 rc = set->cur_waiters[i]->callback(
133 set->cur_waiters[i]->arg);
136 waiter_remove(set->cur_waiters[i]);