summaryrefslogtreecommitdiffstats
path: root/lib/waiter
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2013-05-16 20:39:27 +0800
committerJeremy Kerr <jk@ozlabs.org>2013-05-21 15:29:43 +0800
commit7911281337857bd0f13e5945f6e70bb4af7388a0 (patch)
treea428f4ad4ca7cb8aab814facc2b71577bae3759c /lib/waiter
parent57ee6ff66071deb4e03f414ed00433061b8bef93 (diff)
downloadtalos-petitboot-7911281337857bd0f13e5945f6e70bb4af7388a0.tar.gz
talos-petitboot-7911281337857bd0f13e5945f6e70bb4af7388a0.zip
lib/waiter: allocate waiters separately from set->waiters
Since we reallocate set->waiters, we can't hand out pointers to within that array. Instead, this change allocates the 'struct waiter's separately from the set->waiters array. Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'lib/waiter')
-rw-r--r--lib/waiter/waiter.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/lib/waiter/waiter.c b/lib/waiter/waiter.c
index ac28436..bb25784 100644
--- a/lib/waiter/waiter.c
+++ b/lib/waiter/waiter.c
@@ -16,7 +16,7 @@ struct waiter {
};
struct waitset {
- struct waiter *waiters;
+ struct waiter **waiters;
int n_waiters;
struct pollfd *pollfds;
int n_pollfds;
@@ -36,18 +36,22 @@ void waitset_destroy(struct waitset *set)
struct waiter *waiter_register(struct waitset *set, int fd, int events,
waiter_cb callback, void *arg)
{
- struct waiter *waiters, *waiter;
+ struct waiter **waiters, *waiter;
waiters = talloc_realloc(set, set->waiters,
- struct waiter, set->n_waiters + 1);
+ struct waiter *, set->n_waiters + 1);
if (!waiters)
return NULL;
- set->n_waiters++;
set->waiters = waiters;
+ set->n_waiters++;
+
+ waiter = talloc(set->waiters, struct waiter);
+ if (!waiter)
+ return NULL;
- waiter = &set->waiters[set->n_waiters - 1];
+ set->waiters[set->n_waiters - 1] = waiter;
waiter->set = set;
waiter->fd = fd;
@@ -63,15 +67,20 @@ void waiter_remove(struct waiter *waiter)
struct waitset *set = waiter->set;
int i;
- i = waiter - set->waiters;
- assert(i >= 0 && i < set->n_waiters);
+ for (i = 0; i < set->n_waiters; i++)
+ if (set->waiters[i] == waiter)
+ break;
+
+ assert(i < set->n_waiters);
set->n_waiters--;
memmove(&set->waiters[i], &set->waiters[i+1],
(set->n_waiters - i) * sizeof(set->waiters[0]));
- set->waiters = talloc_realloc(set->waiters, set->waiters, struct waiter,
- set->n_waiters);
+ set->waiters = talloc_realloc(set->waiters, set->waiters,
+ struct waiter *, set->n_waiters);
+
+ talloc_free(waiter);
}
int waiter_poll(struct waitset *set)
@@ -85,8 +94,8 @@ int waiter_poll(struct waitset *set)
}
for (i = 0; i < set->n_waiters; i++) {
- set->pollfds[i].fd = set->waiters[i].fd;
- set->pollfds[i].events = set->waiters[i].events;
+ set->pollfds[i].fd = set->waiters[i]->fd;
+ set->pollfds[i].events = set->waiters[i]->events;
set->pollfds[i].revents = 0;
}
@@ -97,10 +106,10 @@ int waiter_poll(struct waitset *set)
for (i = 0; i < set->n_waiters; i++) {
if (set->pollfds[i].revents) {
- rc = set->waiters[i].callback(set->waiters[i].arg);
+ rc = set->waiters[i]->callback(set->waiters[i]->arg);
if (rc)
- waiter_remove(&set->waiters[i]);
+ waiter_remove(set->waiters[i]);
}
}
OpenPOWER on IntegriCloud