OpenCBDC Transaction Processor
Loading...
Searching...
No Matches
epoll_event_handler.cpp
Go to the documentation of this file.
1// Copyright (c) 2022 MIT Digital Currency Initiative,
2// Federal Reserve Bank of Boston
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
7
8#include <array>
9#include <chrono>
10#include <cstdio>
11#include <iostream>
12#include <sys/epoll.h>
13#include <unistd.h>
14
15namespace cbdc::rpc {
17 close(m_epoll);
18 }
19
21 return (m_epoll = epoll_create1(0)) != -1;
22 }
23
24 void epoll_event_handler::set_timeout(long timeout_ms) {
25 if(timeout_ms == -1) {
26 m_timeout_enabled = false;
27 m_timeout_ms = 1000;
28 return;
29 }
30 m_timeout_enabled = true;
31 m_timeout_ms = timeout_ms;
32 }
33
35 int retval{};
36 if(et == event_type::remove) {
37 retval = epoll_ctl(m_epoll, EPOLL_CTL_DEL, fd, nullptr);
38 m_tracked.erase(fd);
39 } else {
40 epoll_event ev{};
41 ev.data.fd = fd;
42 ev.events = EPOLLET;
43 if(et == event_type::in || et == event_type::inout) {
44 ev.events |= EPOLLIN;
45 }
46 if(et == event_type::out || et == event_type::inout) {
47 ev.events |= EPOLLOUT;
48 }
49 auto it = m_tracked.find(fd);
50 if(it == m_tracked.end()) {
51 retval = epoll_ctl(m_epoll, EPOLL_CTL_ADD, fd, &ev);
52 m_tracked.insert(fd);
53 } else {
54 retval = epoll_ctl(m_epoll, EPOLL_CTL_MOD, fd, &ev);
55 }
56 }
57
58 if(retval == -1) {
59 perror("epoll_ctl");
60 }
61 }
62
63 auto epoll_event_handler::poll() -> std::optional<std::vector<event>> {
64 constexpr auto n_events = 1024;
65 auto evs = std::array<struct epoll_event, n_events>();
66 auto start_time = std::chrono::high_resolution_clock::now();
67 auto event_count = epoll_wait(m_epoll,
68 evs.data(),
69 n_events,
70 static_cast<int>(m_timeout_ms));
71 if(event_count == -1) {
72 perror("epoll_wait");
73 return std::nullopt;
74 }
75
76 auto ret = std::vector<event>();
77
78 if(m_timeout_enabled) {
79 auto end_time = std::chrono::high_resolution_clock::now();
80 if(end_time - start_time > std::chrono::milliseconds(m_timeout_ms)
81 && event_count == 0) {
82 ret.emplace_back(0, true);
83 m_timeout_enabled = false;
84 m_timeout_ms = 1000;
85 }
86 }
87
88 for(size_t i = 0; i < static_cast<size_t>(event_count); i++) {
89 auto& ev = evs[i];
90 auto fd = ev.data.fd;
91 ret.emplace_back(fd, false);
92 }
93
94 /* std::cout << (void*)this << "tracking: " << m_tracked.size() << "
95 events: " << ret.size() << " timeout: " << m_timeout_enabled << " " <<
96 m_timeout_ms << std::endl; */
97 return ret;
98 }
99}
auto init() -> bool override
Initializes the event handler.
void set_timeout(long timeout_ms) override
Sets the timeout for poll to return even if there are no events.
auto poll() -> std::optional< std::vector< event > > override
Wait for events on tracked file descriptors.
void register_fd(int fd, event_type et) override
Registers a file descriptor to track for events.
event_type
Type of event to register interest in.
@ remove
Remove file descriptor.
@ inout
Read and write events.