Skip to content

Commit ac0e5aa

Browse files
BonnyAD9sedmicha
authored andcommitted
TCP - Craete C++ epoll wrapper
1 parent d144251 commit ac0e5aa

File tree

3 files changed

+118
-0
lines changed

3 files changed

+118
-0
lines changed

src/plugins/input/tcp/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ add_library(tcp-input MODULE
55
src/ByteVector.cpp
66
src/DecodeBuffer.cpp
77
src/Connection.cpp
8+
src/Epoll.cpp
89
)
910

1011
if (CMAKE_HOST_SYSTEM_NAME STREQUAL "FreeBSD" OR CMAKE_HOST_SYSTEM_NAME STREQUAL "OpenBSD")
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* \file
3+
* \author Jakub Antonín Štigler <[email protected]>
4+
* \brief C++ wrapper around epoll (source file)
5+
* \date 2024
6+
*
7+
* Copyright: (C) 2023 CESNET, z.s.p.o.
8+
* SPDX-License-Identifier: BSD-3-Clause
9+
*/
10+
11+
#include "Epoll.hpp"
12+
13+
#include <stdexcept> // runtime_error
14+
#include <cerrno> // errno, EINTR
15+
#include <string> // string
16+
17+
#include <sys/epoll.h> // epoll_event, epoll_create, EPOLLIN, EPOLL_CT_ADD, epoll_ctl, EPOLL_CTL_DEL
18+
19+
#include <ipfixcol2.h> // ipx_strerror
20+
21+
#include "UniqueFd.hpp" // UniqueFd
22+
23+
namespace tcp_in {
24+
25+
Epoll::Epoll() : m_fd(epoll_create(1)) {
26+
if (!m_fd) {
27+
const char *err_str;
28+
ipx_strerror(errno, err_str);
29+
throw std::runtime_error("Failed to create epoll: " + std::string(err_str));
30+
}
31+
}
32+
33+
void Epoll::add(int fd, void *data) {
34+
epoll_event ev;
35+
ev.events = EPOLLIN;
36+
if (data) {
37+
ev.data.ptr = data;
38+
} else {
39+
ev.data.fd = fd;
40+
}
41+
if (epoll_ctl(m_fd.get(), EPOLL_CTL_ADD, fd, &ev) == -1) {
42+
const char *err_str;
43+
ipx_strerror(errno, err_str);
44+
throw std::runtime_error("Failed to add to epoll: " + std::string(err_str));
45+
}
46+
}
47+
48+
int Epoll::wait(epoll_event *events, int max_events, int timeout) {
49+
int ev_valid = epoll_wait(m_fd.get(), events, max_events, timeout);
50+
if (ev_valid == -1) {
51+
if (errno == EINTR) {
52+
return 0;
53+
}
54+
}
55+
56+
return ev_valid;
57+
}
58+
59+
} // namespace tcp_in
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* \file
3+
* \author Jakub Antonín Štigler <[email protected]>
4+
* \brief C++ wrapper around epoll (header file)
5+
* \date 2024
6+
*
7+
* Copyright: (C) 2023 CESNET, z.s.p.o.
8+
* SPDX-License-Identifier: BSD-3-Clause
9+
*/
10+
11+
#pragma once
12+
13+
#include <sys/epoll.h> // epoll_event
14+
15+
#include "UniqueFd.hpp" // UniqueFd
16+
17+
namespace tcp_in {
18+
19+
class Epoll {
20+
public:
21+
/**
22+
* @brief Craetes empty epoll.
23+
* @throws when fails to create epoll.
24+
*/
25+
Epoll();
26+
27+
/**
28+
* @brief Add file descriptor to the epoll.
29+
* @param fd File descriptor to add.
30+
* @param [in] data data asociated with the file descriptor, when null, descriptor is set as
31+
* data
32+
* @throws when fails to add to the epoll.
33+
*/
34+
void add(int fd, void *data);
35+
36+
/**
37+
* @brief Waits for any of the file descriptors in the epoll to be active.
38+
* @param[out] ev store all active descriptors here
39+
* @param max_events max number of events to store in `events`
40+
* @param timeout maximum time to wait in milliseconds, -1 for infinite wait
41+
* @returns Number of events written to `events`, negative on error (errno is set)
42+
*/
43+
int wait(epoll_event *events, int max_events, int timeout = -1);
44+
45+
/**
46+
* @brief Removes file descriptor from the epoll.
47+
* @param fd File descriptor to remove from the epoll.
48+
* @return true on success, otherwise false
49+
*/
50+
bool remove(int fd) noexcept {
51+
return epoll_ctl(m_fd.get(), EPOLL_CTL_DEL, fd, nullptr) == 0;
52+
}
53+
54+
private:
55+
UniqueFd m_fd;
56+
};
57+
58+
} // namespace tcp_in

0 commit comments

Comments
 (0)