SNode.C
Loading...
Searching...
No Matches
DescriptorEventPublisher.cpp
Go to the documentation of this file.
1/*
2 * SNode.C - a slim toolkit for network communication
3 * Copyright (C) Volker Christian <me@vchrist.at>
4 * 2020, 2021, 2022, 2023, 2024, 2025
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "core/multiplexer/epoll/DescriptorEventPublisher.h"
21
22#include "core/DescriptorEventReceiver.h"
23
24#ifndef DOXYGEN_SHOULD_SKIP_THIS
25
26#include "utils/PreserveErrno.h"
27
28#include <cerrno>
29
30#endif /* DOXYGEN_SHOULD_SKIP_THIS */
31
32namespace core::multiplexer::epoll {
33
34 DescriptorEventPublisher::EPollEvents::EPollEvents(int& epfd, uint32_t events)
35 : epfd(epfd)
36 , events(events) {
37 epfd = core::system::epoll_create1(EPOLL_CLOEXEC);
38 ePollEvents.resize(1);
39 }
40
42 const utils::PreserveErrno preserveErrno;
43
44 epoll_event ePollEvent{};
45
46 ePollEvent.data.ptr = eventReceiver;
47 ePollEvent.events = events;
48
49 if (core::system::epoll_ctl(epfd, EPOLL_CTL_ADD, eventReceiver->getRegisteredFd(), &ePollEvent) == 0) {
50 interestCount++;
51
52 if (interestCount >= ePollEvents.size()) {
53 ePollEvents.resize(ePollEvents.size() * 2);
54 }
55 } else if (errno == EEXIST) {
56 muxMod(eventReceiver->getRegisteredFd(), events, eventReceiver);
57 }
58 }
59
61 const utils::PreserveErrno preserveErrno;
62
63 if (core::system::epoll_ctl(epfd, EPOLL_CTL_DEL, fd, nullptr) == 0 || errno == EBADF) {
64 interestCount--;
65
66 if (ePollEvents.size() > (interestCount * 2) + 1) {
67 ePollEvents.resize(ePollEvents.size() / 2);
68 ePollEvents.shrink_to_fit();
69 }
70 }
71 }
72
73 void DescriptorEventPublisher::EPollEvents::muxMod(int fd, uint32_t events, core::DescriptorEventReceiver* eventReceiver) const {
74 const utils::PreserveErrno preserveErrno;
75
76 epoll_event ePollEvent{events, {eventReceiver}};
77
78 core::system::epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ePollEvent);
79 }
80
82 muxMod(eventReceiver->getRegisteredFd(), events, eventReceiver);
83 }
84
86 muxMod(eventReceiver->getRegisteredFd(), 0, eventReceiver);
87 }
88
90 return epfd;
91 }
92
94 return ePollEvents.data();
95 }
96
98 return static_cast<int>(interestCount);
99 }
100
101 DescriptorEventPublisher::DescriptorEventPublisher(const std::string& name, int& epfd, uint32_t events, uint32_t revents)
102 : core::DescriptorEventPublisher(name)
104 , revents(revents) {
105 }
106
108 ePollEvents.muxAdd(eventReceiver);
109 }
110
112 ePollEvents.muxDel(fd);
113 }
114
116 ePollEvents.muxOn(eventReceiver);
117 }
118
120 ePollEvents.muxOff(eventReceiver);
121 }
122
124 const int count = core::system::epoll_wait(ePollEvents.getEPFd(), ePollEvents.getEvents(), ePollEvents.getInterestCount(), 0);
125
126 for (int i = 0; i < count; i++) {
127 const epoll_event& ev = ePollEvents.getEvents()[i];
128 core::DescriptorEventReceiver* eventReceiver = static_cast<core::DescriptorEventReceiver*>(ev.data.ptr);
129 if (eventReceiver != nullptr && (ev.events & revents) != 0) {
130 eventCounter++;
131 eventReceiver->span();
132 }
133 }
134 }
135
136} // namespace core::multiplexer::epoll
void muxAdd(core::DescriptorEventReceiver *eventReceiver)
void muxMod(int fd, uint32_t events, core::DescriptorEventReceiver *eventReceiver) const
void muxOff(core::DescriptorEventReceiver *eventReceiver)
void muxAdd(core::DescriptorEventReceiver *eventReceiver) override
DescriptorEventPublisher(const std::string &name, int &epfd, uint32_t events, uint32_t revents)
void muxOff(core::DescriptorEventReceiver *eventReceiver) override
void muxOn(core::DescriptorEventReceiver *eventReceiver) override
int epoll_create1(int flags)
Definition epoll.cpp:30
int epoll_ctl(int epfd, int op, int fd, epoll_event *event)
Definition epoll.cpp:45