]> git.ozlabs.org Git - petitboot/blob - lib/waiter/waiter.c
Fix waiter alloc
[petitboot] / lib / waiter / waiter.c
1
2 #include <poll.h>
3 #include <string.h>
4 #include <assert.h>
5
6 #include <talloc/talloc.h>
7
8 #include "waiter.h"
9
10 struct waiter {
11         int             fd;
12         int             events;
13         waiter_cb       callback;
14         void            *arg;
15 };
16
17 static struct waiter *waiters;
18 static int n_waiters;
19
20 struct waiter *waiter_register(int fd, int events,
21                 waiter_cb callback, void *arg)
22 {
23         struct waiter *waiter;
24
25         n_waiters++;
26
27         waiters = talloc_realloc(NULL, waiters, struct waiter, n_waiters);
28         waiter = &waiters[n_waiters - 1];
29
30         waiter->fd = fd;
31         waiter->events = events;
32         waiter->callback = callback;
33         waiter->arg = arg;
34
35         return 0;
36 }
37
38 void waiter_remove(struct waiter *waiter)
39 {
40         int i;
41
42         i = waiter - waiters;
43         assert(i >= 0 && i < n_waiters);
44
45         n_waiters--;
46         memmove(&waiters[i], &waiters[i+1], n_waiters - i);
47
48         waiters = talloc_realloc(NULL, waiters, struct waiter, n_waiters);
49 }
50
51 int waiter_poll(void)
52 {
53         static struct pollfd *pollfds;
54         static int n_pollfds;
55         int i, rc;
56
57         if (n_waiters != n_pollfds) {
58                 pollfds = talloc_realloc(NULL, pollfds,
59                                 struct pollfd, n_waiters);
60                 n_pollfds = n_waiters;
61         }
62
63         for (i = 0; i < n_waiters; i++) {
64                 pollfds[i].fd = waiters[i].fd;
65                 pollfds[i].events = waiters[i].events;
66                 pollfds[i].revents = 0;
67         }
68
69         rc = poll(pollfds, n_waiters, -1);
70
71         if (rc <= 0)
72                 return rc;
73
74         for (i = 0; i < n_waiters; i++) {
75                 if (pollfds[i].revents) {
76                         rc = waiters[i].callback(waiters[i].arg);
77
78                         if (rc)
79                                 waiter_remove(&waiters[i]);
80                 }
81         }
82
83         return 0;
84 }