#include <stdbool.h>
#include <string.h>
#include <assert.h>
+#include <errno.h>
#include <sys/time.h>
#include <talloc/talloc.h>
#include "waiter.h"
struct waiter {
+ struct waitset *set;
enum {
WAITER_IO,
WAITER_TIME,
- } type;
- struct waitset *set;
- int fd;
- int events;
- struct timeval timeout;
+ } type;
+ union {
+ struct {
+ int fd;
+ int events;
+ } io;
+ struct timeval timeout;
+ };
waiter_cb callback;
void *arg;
return set;
}
-void waitset_destroy(struct waitset *set)
-{
- talloc_free(set);
-}
-
static struct waiter *waiter_new(struct waitset *set)
{
struct waiter **waiters, *waiter;
- waiter = talloc(set->waiters, struct waiter);
+ waiter = talloc(set, struct waiter);
if (!waiter)
return NULL;
waiter->type = WAITER_IO;
waiter->set = set;
- waiter->fd = fd;
- waiter->events = events;
+ waiter->io.fd = fd;
+ waiter->io.events = events;
waiter->callback = callback;
waiter->arg = arg;
memmove(&set->waiters[i], &set->waiters[i+1],
(set->n_waiters - i) * sizeof(set->waiters[0]));
- set->waiters = talloc_realloc(set->waiters, set->waiters,
+ set->waiters = talloc_realloc(set, set->waiters,
struct waiter *, set->n_waiters);
set->waiters_changed = true;
set->n_time_waiters = n_time;
}
- /* 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;
+ i_io = 0;
+ i_time = 0;
- 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;
+ for (i = 0; i < set->n_waiters; i++) {
+ struct waiter *waiter = set->waiters[i];
- set->time_waiters[i_time] = waiter;
- i_time++;
+ /* IO waiters: copy to io_waiters, populate pollfds */
+ if (waiter->type == WAITER_IO) {
+ set->pollfds[i_io].fd = waiter->io.fd;
+ set->pollfds[i_io].events = waiter->io.events;
+ set->io_waiters[i_io] = waiter;
+ i_io++;
+ }
+
+ /* time waiters: copy to time_waiters, calculate next expiry */
+ if (waiter->type == WAITER_TIME) {
+ if (!timerisset(&set->next_timeout) ||
+ timercmp(&waiter->timeout,
+ &set->next_timeout, <))
+ set->next_timeout = waiter->timeout;
+
+ set->time_waiters[i_time] = waiter;
+ i_time++;
+ }
}
}
timeout_ms = -1;
}
-
rc = poll(set->pollfds, set->n_io_waiters, timeout_ms);
- if (rc < 0)
+ 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];