1 #include "hmbdc/Copyright.hpp" 3 #include "hmbdc/pattern/GuardedSingleton.hpp" 4 #include "hmbdc/Config.hpp" 5 #include "hmbdc/Compile.hpp" 15 #include <sys/epoll.h> 18 namespace hmbdc {
namespace app {
namespace utils {
21 #ifndef HMBDC_NO_EPOLL 26 EPOLLOUT = ::EPOLLOUT,
30 static void initialize() {
34 void setWaitTime(
int t) {
38 void add(uint32_t events,
EpollFd&);
45 EpollTask(
size_t maxFdCount = HMBDC_EPOLL_FD_MAX);
47 void setPollPending() { pollPending_ =
true; }
51 std::atomic<bool> pollPending_ =
false;
53 int timeoutMillisec_ = 0;
63 static void initialize() {
67 void add(uint32_t events, EpollFd&);
74 void setPollPending() {}
75 EpollTask(
size_t maxFdCount = HMBDC_EPOLL_FD_MAX);
93 , fdReadyLocal_(
false)
99 utils::EpollTask::instance().del(*
this);
105 if (hmbdc_likely(fdReadyLocal_)) {
108 EpollTask::instance().setPollPending();
110 return fdReadyLocal_ = __atomic_exchange_n(&fdReady_,
false, __ATOMIC_RELAXED);
115 fdReadyLocal_ =
false;
116 if (errno != EAGAIN) {
117 if (!utils::EpollTask::instance().del(*
this)) {
136 #ifndef HMBDC_NO_EPOLL 137 #include <sys/epoll.h> 138 namespace hmbdc {
namespace app {
namespace utils {
142 EpollTask(
size_t maxFdCount)
144 epollFd_ = epoll_create(maxFdCount);
145 if (epollFd_ == -1) {
146 HMBDC_THROW(std::runtime_error,
"cannot create epoll errno=" << errno);
153 add(uint32_t events, EpollFd& t) {
154 struct epoll_event ev;
156 ev.data.ptr = &t.fdReady_;
157 if (epoll_ctl(epollFd_, EPOLL_CTL_ADD, t.fd, &ev) == -1) {
158 HMBDC_THROW(std::runtime_error,
"cannot add into epoll, errno=" << errno);
166 return epoll_ctl(epollFd_, EPOLL_CTL_DEL, t.fd, NULL) != -1;
173 if (!pollPending_)
return;
174 struct epoll_event events[HMBDC_EPOLL_FD_MAX];
176 nfds = epoll_wait(epollFd_, events, HMBDC_EPOLL_FD_MAX, timeoutMillisec_);
177 if (hmbdc_unlikely(nfds == -1 && errno != EINTR)) {
178 HMBDC_THROW(std::runtime_error,
"epoll_pwait errno=" << errno);
180 for (
int i = 0; i < nfds; ++i) {
181 auto& sentinel = *
static_cast<bool*
>(events[i].data.ptr);
184 pollPending_ =
false;
185 if (nfds > 0) __atomic_thread_fence(__ATOMIC_RELEASE);
200 namespace hmbdc {
namespace app {
namespace utils {
204 EpollTask(
size_t maxFdCount)
206 , maxFdCount_(maxFdCount)
207 , pollFds_(new ::pollfd[maxFdCount])
208 , sentinels_(new bool* [maxFdCount]) {
209 for (
auto i = 0u; i < maxFdCount; ++i) {
211 sentinels_[i] =
nullptr;
218 add(uint32_t events, EpollFd& t) {
219 std::lock_guard<std::mutex> g(lock_);
220 auto slot = std::find_if(pollFds_, pollFds_ + maxFdCount_
221 , [](pollfd& pf){
return pf.fd < 0;});
222 if (slot != pollFds_ + maxFdCount_) {
224 slot->events = (short)events;
226 sentinels_[slot - pollFds_] = &t.fdReady_;
228 HMBDC_THROW(std::runtime_error,
"cannot add into poll, errno=" << errno);
236 std::lock_guard<std::mutex> g(lock_);
237 auto slot = std::find_if(pollFds_, pollFds_ + maxFdCount_
238 , [fd = t.fd](pollfd& pf){return pf.fd == fd;});
239 if (slot != pollFds_ + maxFdCount_) {
240 slot->fd = -slot->fd;
241 sentinels_[slot - pollFds_] =
nullptr;
252 if (!lock_.try_lock())
return;
253 auto nfds = ::poll(pollFds_, (nfds_t)maxFdCount_, 0);
254 for (
auto i = 0u; nfds > 0 && i < maxFdCount_; ++i) {
255 if (pollFds_[i].revents) {
256 *sentinels_[i] =
true;
262 if (hmbdc_unlikely(nfds< 0 && errno != EINTR)) {
263 HMBDC_THROW(std::runtime_error,
"poll errno=" << errno);
base for the Singleton that works with SingletonGuardian
Definition: GuardedSingleton.hpp:53
RAII representing the lifespan of the underlying Singleton which also ganrantees the singularity of u...
Definition: GuardedSingleton.hpp:20
Definition: EpollTask.hpp:22
Definition: EpollTask.hpp:87