-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathEpoll.cpp
130 lines (112 loc) · 3.22 KB
/
Epoll.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
/*************************************************************************
> File Name: Epoll.cpp
> Author: zhangfeng
> Mail: [email protected]
> Created Time: Mon 07 Oct 2019 11:14:49 AM CST
> Target:
************************************************************************/
#include "Epoll.h"
#include "Util.h"
#include "base/Logging.h"
#include <sys/epoll.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <queue>
#include <deque>
#include <assert.h>
#include <arpa/inet.h>
#include <iostream>
using namespace std;
const int EVENTSNUM = 4 * 1024;
const int EPOLLWAIT_TIME = 10000;
typedef shared_ptr<Channel> SP_Channel;
Epoll::Epoll() :
epollFd_(epoll_create1(EPOLL_CLOEXEC)),
events_(EVENTSNUM)
{
assert(epollFd_ > 0);
}
Epoll::~Epoll() {
}
void Epoll::epoll_add(SP_Channel request, int timeout) {
int fd = request->getFd();
if(timeout > 0) {
add_timer(request, timeout);
fd2http_[fd] = request->getHolder();
}
struct epoll_event event;
event.data.fd = fd;
event.events = request->getEvents();
request->EqualAndUpdateLastEvents();
fd2chan_[fd] = request;
if(epoll_ctl(epollFd_, EPOLL_CTL_ADD, fd, &event) < 0) {
perror("epoll_add failed");
fd2chan_[fd].reset();
}
}
void Epoll::epoll_mod(SP_Channel request, int timeout) {
if(timeout > 0) {
add_timer(request, timeout);
}
int fd = request->getFd();
if(!request->EqualAndUpdateLastEvents()) {
struct epoll_event event;
event.data.fd = fd;
event.events = request->getEvents();
if(epoll_ctl(epollFd_, EPOLL_CTL_MOD, fd, &event) < 0) {
perror("epoll_mod error");
fd2chan_[fd].reset();
}
}
}
void Epoll::epoll_del(SP_Channel request) {
int fd = request->getFd();
struct epoll_event event;
event.data.fd = fd;
event.events = request->getLastEvents();
if(epoll_ctl(epollFd_, EPOLL_CTL_DEL, fd, &event) < 0) {
perror("epoll_del error");
}
fd2chan_[fd].reset();
fd2http_[fd].reset();
}
std::vector<SP_Channel> Epoll::poll() {
while(true) {
int event_count = epoll_wait(epollFd_, &*events_.begin(), events_.size(), EPOLLWAIT_TIME);
if(event_count < 0) {
perror("epoll wait error");
}
std::vector<SP_Channel> req_data = getEventsRequest(event_count);
if(req_data.size() > 0) {
return req_data;
}
}
}
void Epoll::handleExpired() {
timerManager_.handleExpiredEvent();
}
std::vector<SP_Channel> Epoll::getEventsRequest(int events_num) {
std::vector<SP_Channel> req_data;
for(int i = 0; i < events_num; i++) {
int fd = events_[i].data.fd;
SP_Channel cur_req = fd2chan_[fd];
if(cur_req) {
cur_req->setRevents(events_[i].events);
cur_req->setEvents(0);
req_data.push_back(cur_req);
} else {
LOG << "SP_Channel cur_req is invalid";
}
}
return req_data;
}
void Epoll::add_timer(SP_Channel request, int timeout) {
shared_ptr<HttpData> t = request->getHolder();
if(t) {
timerManager_.addTimer(t, timeout);
} else {
LOG << "timer add failed";
}
}