-
Notifications
You must be signed in to change notification settings - Fork 0
/
eventhandler.cpp
70 lines (57 loc) · 1.36 KB
/
eventhandler.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
#include "eventhandler.hpp"
#include <sys/epoll.h>
#include <unistd.h>
#include <stdexcept>
#include <iostream>
EventHandler::EventHandler() : killed(false)
{
epfd = epoll_create(16);
if (epfd < 0)
throw std::runtime_error("Failed to create epoll.\n");
}
EventHandler::~EventHandler()
{
close(epfd);
}
void EventHandler::add(std::weak_ptr<EventHandled> handler)
{
auto fd_ptr = handler.lock();
for (auto fd : fd_ptr->pollfds())
{
struct epoll_event event{};
event.events = fd.events;
event.data.fd = fd.fd;
cb_map[event.data.fd] = [this, handler]() {
if (auto tmp = handler.lock())
tmp->handle(*this);
};
if (epoll_ctl(epfd, EPOLL_CTL_ADD, event.data.fd, &event) < 0)
throw std::runtime_error("Failed to add epoll fd to list.\n");
}
}
void EventHandler::remove(const EventHandled &handler)
{
for (auto fd : handler.pollfds())
{
cb_map[fd.fd] = {};
epoll_ctl(epfd, EPOLL_CTL_DEL, fd.fd, nullptr);
}
}
void EventHandler::kill()
{
killed = true;
}
bool EventHandler::wait()
{
struct epoll_event events[16];
int ret = epoll_wait(epfd, events, 16, -1);
if (ret < 0)
throw std::runtime_error("epoll_wait() failed.\n");
for (int i = 0; i < ret; i++)
{
auto cb = cb_map[events[i].data.fd];
if (cb)
cb();
}
return !killed;
}