-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathreactor.cc
66 lines (48 loc) · 1.09 KB
/
reactor.cc
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
#include "reactor.h"
#include <lace/try.h>
#include "trigger.h"
#include <cassert>
#include <unistd.h>
#include <sys/epoll.h>
reactor::reactor()
: fd(file_descriptor(TRY(epoll_create1, EPOLL_CLOEXEC)))
, armed_triggers(0)
{ }
reactor::~reactor() { assert(!armed()); }
bool reactor::armed() const { return armed_triggers; }
namespace {
int
pull_events(context::queue & q, int fd, int events_max, bool block) {
struct epoll_event events[events_max];
int n = epoll_wait(fd, events, events_max, block ? -1 : 0);
if (n < 0)
return 0;
for (int i = 0 ; i < n ; ++i)
if (events[i].data.ptr)
q.enqueue(static_cast<trigger*>(events[i].data.ptr)->fire());
return n;
}
}
int
reactor::poll(context::queue & q) {
const unsigned max = 16;
int c = 0, n;
do {
n = pull_events(q, fd, max, false);
c += n;
} while (n == max);
return c;
}
int
reactor::wait(context::queue & q) {
assert(armed());
const unsigned max = 16;
int n;
do {
n = pull_events(q, fd, max, true);
} while (!n);
if (n == max)
n += poll(q);
return n;
}
//