]> git.ozlabs.org Git - petitboot/blob - lib/waiter/waiter.c
Add DEVPATH to udev_print_event()
[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         
29         if(!waiters)
30                 return NULL;
31         
32         waiter = &waiters[n_waiters - 1];
33
34         waiter->fd = fd;
35         waiter->events = events;
36         waiter->callback = callback;
37         waiter->arg = arg;
38
39         return waiter;
40 }
41
42 void waiter_remove(struct waiter *waiter)
43 {
44         int i;
45
46         i = waiter - waiters;
47         assert(i >= 0 && i < n_waiters);
48
49         n_waiters--;
50         memmove(&waiters[i], &waiters[i+1],
51                 (n_waiters - i) * sizeof(waiters[0]));
52
53         waiters = talloc_realloc(NULL, waiters, struct waiter, n_waiters);
54 }
55
56 int waiter_poll(void)
57 {
58         static struct pollfd *pollfds;
59         static int n_pollfds;
60         int i, rc;
61
62         if (n_waiters != n_pollfds) {
63                 pollfds = talloc_realloc(NULL, pollfds,
64                                 struct pollfd, n_waiters);
65                 n_pollfds = n_waiters;
66         }
67
68         for (i = 0; i < n_waiters; i++) {
69                 pollfds[i].fd = waiters[i].fd;
70                 pollfds[i].events = waiters[i].events;
71                 pollfds[i].revents = 0;
72         }
73
74         rc = poll(pollfds, n_waiters, -1);
75
76         if (rc <= 0)
77                 return rc;
78
79         for (i = 0; i < n_waiters; i++) {
80                 if (pollfds[i].revents) {
81                         rc = waiters[i].callback(waiters[i].arg);
82
83                         if (rc)
84                                 waiter_remove(&waiters[i]);
85                 }
86         }
87
88         return 0;
89 }