-
Notifications
You must be signed in to change notification settings - Fork 0
/
epoll.cc
70 lines (60 loc) · 1.49 KB
/
epoll.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
#include "epoll.h"
#include <sys/epoll.h>
#include <unistd.h>
#include <functional>
#include <iostream>
#include <stdexcept>
Epoll::Epoll() {
epollfd_ = epoll_create1(0);
if (epollfd_ == -1) {
throw std::runtime_error("epoll_create1 failed.");
}
}
Epoll::~Epoll() {
if (epollfd_ != -1) {
close(epollfd_);
}
}
int Epoll::Add(int fd, std::function<void(int)> read_callback) {
if (callbacks_.size() >= kMaxEvents) {
std::cerr << "too many file descriptors to monitor." << std::endl;
return -1;
}
epoll_event event;
event.data.fd = fd;
event.events = EPOLLIN;
if (epoll_ctl(epollfd_, EPOLL_CTL_ADD, fd, &event) == -1) {
std::cerr << "epoll_ctl: add failed." << std::endl;
return -1;
}
callbacks_[fd] = std::move(read_callback);
return 0;
}
int Epoll::Remove(int fd) {
if (epoll_ctl(epollfd_, EPOLL_CTL_DEL, fd, NULL) == -1) {
std::cerr << "epoll_ctl: del failed." << std::endl;
return -1;
}
callbacks_.erase(fd);
return 0;
}
void Epoll::Wait() {
int size = callbacks_.size();
epoll_event events[size];
int num_events = epoll_wait(epollfd_, events, size, 1000);
if (num_events == -1) {
if (errno == EINTR) {
return; // Try again.
} else {
std::cerr << "epoll_wait failed." << std::endl;
return;
}
}
for (int i = 0; i < num_events; ++i) {
int fd = events[i].data.fd;
if (callbacks_.count(fd) && events[i].events & EPOLLIN &&
callbacks_[fd] != nullptr) {
callbacks_[fd](fd);
}
}
}