-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfde.cpp
132 lines (113 loc) · 3.16 KB
/
fde.cpp
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
Copyright (c) 2012-2014 The SSDB Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
*/
#include "fde.h"
struct Fdevent* Fdevents::get_fde(int fd) {
while ((int)events.size() <= fd) {
struct Fdevent* fde = new Fdevent();
fde->fd = events.size();
fde->s_flags = FDEVENT_NONE;
fde->data.num = 0;
fde->data.ptr = NULL;
events.push_back(fde);
}
return events[fd];
}
Fdevents::Fdevents() {
ep_fd = epoll_create(1024);
}
Fdevents::~Fdevents() {
for (int i = 0; i < (int)events.size(); i++) {
delete events[i];
}
if (ep_fd) {
::close(ep_fd);
}
events.clear();
ready_events.clear();
}
bool Fdevents::isset(int fd, int flag) {
struct Fdevent* fde = get_fde(fd);
return (bool)(fde->s_flags & flag);
}
int Fdevents::set(int fd, int flags, int data_num, void* data_ptr) {
struct Fdevent* fde = get_fde(fd);
if (fde->s_flags & flags) {
return 0;
}
int ctl_op = fde->s_flags ? EPOLL_CTL_MOD : EPOLL_CTL_ADD;
fde->s_flags |= flags;
fde->data.num = data_num;
fde->data.ptr = data_ptr;
struct epoll_event epe;
epe.data.ptr = fde;
epe.events = 0;
if (fde->s_flags & FDEVENT_IN)
epe.events |= EPOLLIN;
if (fde->s_flags & FDEVENT_OUT)
epe.events |= EPOLLOUT;
int ret = epoll_ctl(ep_fd, ctl_op, fd, &epe);
if (ret == -1) {
return -1;
}
return 0;
}
int Fdevents::del(int fd) {
struct epoll_event epe;
int ret = epoll_ctl(ep_fd, EPOLL_CTL_DEL, fd, &epe);
if (ret == -1) {
return -1;
}
struct Fdevent* fde = get_fde(fd);
fde->s_flags = FDEVENT_NONE;
return 0;
}
int Fdevents::clr(int fd, int flags) {
struct Fdevent* fde = get_fde(fd);
if (!(fde->s_flags & flags)) {
return 0;
}
fde->s_flags &= ~flags;
int ctl_op = fde->s_flags ? EPOLL_CTL_MOD : EPOLL_CTL_DEL;
struct epoll_event epe;
epe.data.ptr = fde;
epe.events = 0;
if (fde->s_flags & FDEVENT_IN)
epe.events |= EPOLLIN;
if (fde->s_flags & FDEVENT_OUT)
epe.events |= EPOLLOUT;
int ret = epoll_ctl(ep_fd, ctl_op, fd, &epe);
if (ret == -1) {
return -1;
}
return 0;
}
const Fdevents::events_t* Fdevents::wait(int timeout_ms) {
ready_events.clear();
int nfds = epoll_wait(ep_fd, ep_events, MAX_FDS, timeout_ms);
if (nfds == -1) {
if (errno == EINTR) {
return &ready_events;
}
return NULL;
}
for (int i = 0; i < nfds; i++) {
struct epoll_event* epe = &ep_events[i];
struct Fdevent* fde = (struct Fdevent*)epe->data.ptr;
fde->events = FDEVENT_NONE;
if (epe->events & EPOLLIN)
fde->events |= FDEVENT_IN;
if (epe->events & EPOLLPRI)
fde->events |= FDEVENT_IN;
if (epe->events & EPOLLOUT)
fde->events |= FDEVENT_OUT;
if (epe->events & EPOLLHUP)
fde->events |= FDEVENT_ERR;
if (epe->events & EPOLLERR)
fde->events |= FDEVENT_ERR;
ready_events.push_back(fde);
}
return &ready_events;
}