forked from song0071000/SimpleReactorImplemention
-
Notifications
You must be signed in to change notification settings - Fork 0
/
event_demultiplexer.cc
99 lines (90 loc) · 2.54 KB
/
event_demultiplexer.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
#include <errno.h>
#include <assert.h>
#include <vector>
#include "event_demultiplexer.h"
namespace reactor
{
EpollDemultiplexer::EpollDemultiplexer()
{
m_epoll_fd = ::epoll_create(FD_SETSIZE);
assert(m_epoll_fd != -1);
m_fd_num = 0;
}
EpollDemultiplexer::~EpollDemultiplexer()
{
::close(m_epoll_fd);
}
int EpollDemultiplexer::WaitEvents(
std::map<handle_t, EventHandler *> * handlers,
int timeout, time_heap* event_timer)
{
std::vector<epoll_event> ep_evts(m_fd_num);
int num = epoll_wait(m_epoll_fd, &ep_evts[0], ep_evts.size(), timeout);
if (num > 0)
{
for (int idx = 0; idx < num; ++idx)
{
handle_t handle = ep_evts[idx].data.fd;
assert(handlers->find(handle) != handlers->end());
if ((ep_evts[idx].events & EPOLLERR) ||
(ep_evts[idx].events & EPOLLHUP))
{
(*handlers)[handle]->HandleError();
}
else
{
if (ep_evts[idx].events & EPOLLIN)
{
(*handlers)[handle]->HandleRead();
}
if (ep_evts[idx].events & EPOLLOUT)
{
(*handlers)[handle]->HandleWrite();
}
}
}
}
if (event_timer != NULL)
{
event_timer->tick();
}
return num;
}
int EpollDemultiplexer::RequestEvent(handle_t handle, event_t evt)
{
epoll_event ep_evt;
ep_evt.data.fd = handle;
ep_evt.events = 0;
if (evt & kReadEvent)
{
ep_evt.events |= EPOLLIN;
}
if (evt & kWriteEvent)
{
ep_evt.events |= EPOLLOUT;
}
ep_evt.events |= EPOLLONESHOT;
if (epoll_ctl(m_epoll_fd, EPOLL_CTL_MOD, handle, &ep_evt) != 0)
{
if (errno == ENOENT)
{
if (epoll_ctl(m_epoll_fd, EPOLL_CTL_ADD, handle, &ep_evt) != 0)
{
return -errno;
}
++m_fd_num;
}
}
return 0;
}
int EpollDemultiplexer::UnrequestEvent(handle_t handle)
{
epoll_event ep_evt;
if (epoll_ctl(m_epoll_fd, EPOLL_CTL_DEL, handle, &ep_evt) != 0)
{
return -errno;
}
--m_fd_num;
return 0;
}
} // namespace reactor