From: Otto Moerbeek Date: Tue, 21 May 2024 08:40:46 +0000 (+0200) Subject: Use RIAA guard for d_inrun, making sure exceptions reset d_inrun X-Git-Tag: rec-5.1.0-beta1~31^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e85f719bdcbe0f30e2629a3734181ff8e77b6a96;p=thirdparty%2Fpdns.git Use RIAA guard for d_inrun, making sure exceptions reset d_inrun --- diff --git a/pdns/devpollmplexer.cc b/pdns/devpollmplexer.cc index 071ee9e945..7a2a3ae9f3 100644 --- a/pdns/devpollmplexer.cc +++ b/pdns/devpollmplexer.cc @@ -140,9 +140,8 @@ void DevPollFDMultiplexer::getAvailableFDs(std::vector& fds, int timeout) int DevPollFDMultiplexer::run(struct timeval* now, int timeout) { - if (d_inrun) { - throw FDMultiplexerException("FDMultiplexer::run() is not reentrant!\n"); - } + InRun guard(d_inrun); + std::vector fds(d_readCallbacks.size() + d_writeCallbacks.size()); struct dvpoll dvp; dvp.dp_nfds = d_readCallbacks.size() + d_writeCallbacks.size(); @@ -160,7 +159,6 @@ int DevPollFDMultiplexer::run(struct timeval* now, int timeout) return 0; } - d_inrun = true; int count = 0; for (int n = 0; n < ret; ++n) { if ((fds.at(n).revents & POLLIN) || (fds.at(n).revents & POLLERR) || (fds.at(n).revents & POLLHUP)) { @@ -180,7 +178,6 @@ int DevPollFDMultiplexer::run(struct timeval* now, int timeout) } } - d_inrun = false; return count; } diff --git a/pdns/epollmplexer.cc b/pdns/epollmplexer.cc index 4ccb0a016c..9d11415d4c 100644 --- a/pdns/epollmplexer.cc +++ b/pdns/epollmplexer.cc @@ -166,9 +166,7 @@ void EpollFDMultiplexer::getAvailableFDs(std::vector& fds, int timeout) int EpollFDMultiplexer::run(struct timeval* now, int timeout) { - if (d_inrun) { - throw FDMultiplexerException("FDMultiplexer::run() is not reentrant!\n"); - } + InRun guard(d_inrun); int ret = epoll_wait(d_epollfd, d_eevents.data(), d_eevents.size(), timeout); gettimeofday(now, nullptr); // MANDATORY @@ -181,8 +179,8 @@ int EpollFDMultiplexer::run(struct timeval* now, int timeout) return 0; } - d_inrun = true; int count = 0; + for (int n = 0; n < ret; ++n) { if ((d_eevents[n].events & EPOLLIN) || (d_eevents[n].events & EPOLLERR) || (d_eevents[n].events & EPOLLHUP)) { const auto& iter = d_readCallbacks.find(d_eevents[n].data.fd); @@ -201,7 +199,6 @@ int EpollFDMultiplexer::run(struct timeval* now, int timeout) } } - d_inrun = false; return count; } diff --git a/pdns/kqueuemplexer.cc b/pdns/kqueuemplexer.cc index e843332601..608ae420d8 100644 --- a/pdns/kqueuemplexer.cc +++ b/pdns/kqueuemplexer.cc @@ -166,9 +166,7 @@ void KqueueFDMultiplexer::getAvailableFDs(std::vector& fds, int timeout) int KqueueFDMultiplexer::run(struct timeval* now, int timeout) { - if (d_inrun) { - throw FDMultiplexerException("FDMultiplexer::run() is not reentrant!\n"); - } + InRun guard(d_inrun); struct timespec ts; ts.tv_sec = timeout / 1000; @@ -186,8 +184,6 @@ int KqueueFDMultiplexer::run(struct timeval* now, int timeout) return 0; } - d_inrun = true; - for (int n = 0; n < ret; ++n) { if (d_kevents[n].filter == EVFILT_READ) { const auto& iter = d_readCallbacks.find(d_kevents[n].ident); @@ -204,7 +200,6 @@ int KqueueFDMultiplexer::run(struct timeval* now, int timeout) } } - d_inrun = false; return ret; } diff --git a/pdns/mplexer.hh b/pdns/mplexer.hh index 0fab107588..cf3f3c5cdf 100644 --- a/pdns/mplexer.hh +++ b/pdns/mplexer.hh @@ -81,6 +81,25 @@ public: minimum value of maxEventsHint and s_maxevents, to reduce memory usage. */ static FDMultiplexer* getMultiplexerSilent(unsigned int maxEventsHint = s_maxevents); + struct InRun { + InRun(const InRun&) = delete; + InRun(InRun&&) = delete; + InRun& operator=(const InRun&) = delete; + InRun& operator=(InRun&&) = delete; + InRun(bool& ref) : + d_inrun(ref) + { + if (d_inrun) { + throw FDMultiplexerException("FDMultiplexer::run() is not reentrant!"); + } + d_inrun = true; + } + ~InRun() { + d_inrun = false; + } + bool& d_inrun; + }; + /* tv will be updated to 'now' before run returns */ /* timeout is in ms, 0 will return immediately, -1 will block until at least one descriptor is ready */ diff --git a/pdns/pollmplexer.cc b/pdns/pollmplexer.cc index 936c0c5088..ed63c601fe 100644 --- a/pdns/pollmplexer.cc +++ b/pdns/pollmplexer.cc @@ -122,9 +122,7 @@ void PollFDMultiplexer::getAvailableFDs(std::vector& fds, int timeout) int PollFDMultiplexer::run(struct timeval* now, int timeout) { - if (d_inrun) { - throw FDMultiplexerException("FDMultiplexer::run() is not reentrant!\n"); - } + InRun guard(d_inrun); auto pollfds = preparePollFD(); if (pollfds.empty()) { @@ -139,7 +137,6 @@ int PollFDMultiplexer::run(struct timeval* now, int timeout) throw FDMultiplexerException("poll returned error: " + stringerror()); } - d_inrun = true; int count = 0; for (const auto& pollfd : pollfds) { if (pollfd.revents & POLLIN || pollfd.revents & POLLERR || pollfd.revents & POLLHUP) { @@ -159,7 +156,6 @@ int PollFDMultiplexer::run(struct timeval* now, int timeout) } } - d_inrun = false; return count; } diff --git a/pdns/portsmplexer.cc b/pdns/portsmplexer.cc index 86bd563041..c795183829 100644 --- a/pdns/portsmplexer.cc +++ b/pdns/portsmplexer.cc @@ -147,9 +147,7 @@ void PortsFDMultiplexer::getAvailableFDs(std::vector& fds, int timeout) int PortsFDMultiplexer::run(struct timeval* now, int timeout) { - if (d_inrun) { - throw FDMultiplexerException("FDMultiplexer::run() is not reentrant!\n"); - } + InRun guard(d_inrun); struct timespec timeoutspec; timeoutspec.tv_sec = timeout / 1000; @@ -177,7 +175,6 @@ int PortsFDMultiplexer::run(struct timeval* now, int timeout) return 0; } - d_inrun = true; int count = 0; for (unsigned int n = 0; n < numevents; ++n) { if (d_pevents[n].portev_events & POLLIN || d_pevents[n].portev_events & POLLERR || d_pevents[n].portev_events & POLLHUP) { @@ -202,7 +199,6 @@ int PortsFDMultiplexer::run(struct timeval* now, int timeout) } } - d_inrun = false; return count; }