]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Use RIAA guard for d_inrun, making sure exceptions reset d_inrun
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 21 May 2024 08:40:46 +0000 (10:40 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 21 May 2024 13:47:33 +0000 (15:47 +0200)
pdns/devpollmplexer.cc
pdns/epollmplexer.cc
pdns/kqueuemplexer.cc
pdns/mplexer.hh
pdns/pollmplexer.cc
pdns/portsmplexer.cc

index 071ee9e94597a130789639b4ed1b0ddc8d43a32f..7a2a3ae9f309f5bbd6e405d7e133e13147d4333f 100644 (file)
@@ -140,9 +140,8 @@ void DevPollFDMultiplexer::getAvailableFDs(std::vector<int>& 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<struct pollfd> 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;
 }
 
index 4ccb0a016c3d0f04e55d03228fb333f88f210400..9d11415d4ca6d082f30f1a7958fce44886e2f76e 100644 (file)
@@ -166,9 +166,7 @@ void EpollFDMultiplexer::getAvailableFDs(std::vector<int>& 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;
 }
 
index e843332601f2a74cfb4644125bf93aa5990ea6c9..608ae420d8586ff104f4e1c0c4fc074349dc4dfb 100644 (file)
@@ -166,9 +166,7 @@ void KqueueFDMultiplexer::getAvailableFDs(std::vector<int>& 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;
 }
 
index 0fab1075883f23b0bdd86d085eb05915482921a3..cf3f3c5cdfbf2969faed803025df125a966d1009 100644 (file)
@@ -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 */
index 936c0c5088003b1d8e58ed23b0fb255c6277e49b..ed63c601fed1020f0575426f3d144617042bce3d 100644 (file)
@@ -122,9 +122,7 @@ void PollFDMultiplexer::getAvailableFDs(std::vector<int>& 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;
 }
 
index 86bd56304177e5cf4894ee70957602de752111dc..c795183829a75c2419c2d59ca015888666b35940 100644 (file)
@@ -147,9 +147,7 @@ void PortsFDMultiplexer::getAvailableFDs(std::vector<int>& 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;
 }