-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtrigger.cc
113 lines (95 loc) · 2.13 KB
/
trigger.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include "trigger.h"
#include <lace/try.h>
#include "reactor.h"
#include <cassert>
#include <unistd.h>
trigger::trigger(int fd)
: fd_(fd), r_(NULL)
{
ev_.events = EPOLLONESHOT;
ev_.data.ptr = NULL;
}
trigger::trigger(const file_descriptor & fd)
: fd_(fd), r_(NULL)
{
ev_.events = EPOLLONESHOT;
ev_.data.ptr = NULL;
}
trigger::~trigger() { }
int trigger::fd() const { return fd_; }
int trigger::dup() const { return file_descriptor::dup(fd_); }
basic_context *
trigger::wait_for_read() {
arm();
ev_.events = EPOLLRDHUP|EPOLLIN|EPOLLONESHOT;
TRY(epoll_ctl, r_->fd, EPOLL_CTL_MOD, fd_, &ev_);
return static_cast<basic_context*>(this);
}
basic_context *
trigger::wait_for_write() {
arm();
ev_.events = EPOLLOUT|EPOLLONESHOT;
TRY(epoll_ctl, r_->fd, EPOLL_CTL_MOD, fd_, &ev_);
return static_cast<basic_context*>(this);
}
basic_context *
trigger::wait_for_error() {
arm();
ev_.events = EPOLLRDHUP|EPOLLONESHOT;
TRY(epoll_ctl, r_->fd, EPOLL_CTL_MOD, fd_, &ev_);
return static_cast<basic_context*>(this);
}
basic_context *
trigger::wait_for_nothing() {
disarm();
ev_.events = EPOLLONESHOT;
TRY(epoll_ctl, r_->fd, EPOLL_CTL_MOD, fd_, &ev_);
return static_cast<basic_context*>(this);
}
basic_context *
trigger::wait_for_anything() {
arm();
ev_.events = EPOLLRDHUP|EPOLLIN|EPOLLOUT|EPOLLONESHOT;
TRY(epoll_ctl, r_->fd, EPOLL_CTL_MOD, fd_, &ev_);
return static_cast<basic_context*>(this);
}
bool
trigger::readable() const {
assert(!armed());
return ev_.events & EPOLLIN;
}
bool
trigger::writable() const {
assert(!armed());
return ev_.events & EPOLLOUT;
}
basic_context *
trigger::fire() {
assert(armed());
disarm();
return static_cast<basic_context*>(this);
}
void
trigger::arm() {
assert(!armed());
ev_.data.ptr = this;
if (!r_) {
r_ = &reactor::instance();
TRY_ERR(EPERM, epoll_ctl, r_->fd, EPOLL_CTL_ADD, fd_, &ev_);
}
++r_->armed_triggers;
assert(armed());
}
void
trigger::disarm() {
assert(armed());
ev_.data.ptr = NULL;
assert(r_);
--r_->armed_triggers;
assert(!armed());
}
bool
trigger::armed() const {
return ev_.data.ptr == static_cast<const trigger*>(this);
}
//