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