]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Consistently return the number of ready events, not descriptor
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 5 Aug 2021 06:50:55 +0000 (08:50 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 5 Aug 2021 06:50:55 +0000 (08:50 +0200)
We might have two events for the same descriptor, readable AND
writable. It was already counted as two separate events by the
kqueue multiplexer but not by the other ones.

pdns/devpollmplexer.cc
pdns/epollmplexer.cc
pdns/mplexer.hh
pdns/pollmplexer.cc
pdns/portsmplexer.cc
pdns/test-mplexer.cc

index c73c03d28f04e5fb193759dea5224c81763ce140..b0c295862ea9ad4edc62564b1cb9b7aafd8b4c73 100644 (file)
@@ -161,11 +161,13 @@ int DevPollFDMultiplexer::run(struct timeval* now, int timeout)
   }
 
   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)) {
       const auto& iter = d_readCallbacks.find(fds.at(n).fd);
       if (iter != d_readCallbacks.end()) {
         iter->d_callback(iter->d_fd, iter->d_parameter);
+        count++;
       }
     }
 
@@ -173,12 +175,13 @@ int DevPollFDMultiplexer::run(struct timeval* now, int timeout)
       const auto& iter = d_writeCallbacks.find(fds.at(n).fd);
       if (iter != d_writeCallbacks.end()) {
         iter->d_callback(iter->d_fd, iter->d_parameter);
+        count++;
       }
     }
   }
 
   d_inrun = false;
-  return ret;
+  return count;
 }
 
 #if 0
index dc060f13070d3e9332a2dd0dae57fddde838f322..1be901da8e331bac2700c2ff2f9836df99d5b736 100644 (file)
@@ -185,11 +185,13 @@ int EpollFDMultiplexer::run(struct timeval* now, int timeout)
   }
 
   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);
       if (iter != d_readCallbacks.end()) {
         iter->d_callback(iter->d_fd, iter->d_parameter);
+        count++;
       }
     }
 
@@ -197,12 +199,13 @@ int EpollFDMultiplexer::run(struct timeval* now, int timeout)
       const auto& iter = d_writeCallbacks.find(d_eevents[n].data.fd);
       if (iter != d_writeCallbacks.end()) {
         iter->d_callback(iter->d_fd, iter->d_parameter);
+        count++;
       }
     }
   }
 
   d_inrun = false;
-  return ret;
+  return count;
 }
 
 #if 0
index 6ea2e0ea85b7940eb8b3936ad0a8c776de19974b..b5742a8c48cb8e7f53f518b0f067b1d01c321462 100644 (file)
@@ -85,7 +85,8 @@ public:
   /* tv will be updated to 'now' before run returns */
   /* timeout is in ms */
   /* returns 0 on timeout, -1 in case of error (but all implementations
-     actually throw in that case) and the number of ready events otherwise */
+     actually throw in that case) and the number of ready events otherwise.
+     Note that We might have two events (read AND write) for the same descriptor */
   virtual int run(struct timeval* tv, int timeout = 500) = 0;
 
   /* timeout is in ms, 0 will return immediately, -1 will block until at least one FD is ready */
index 924999c1b006626936584eaec2851c88b37cf909..c9fdefb68b7b4b375c79136ef211802b3a9805b2 100644 (file)
@@ -144,13 +144,13 @@ int PollFDMultiplexer::run(struct timeval* now, int timeout)
   }
 
   d_inrun = true;
-
+  int count = 0;
   for (const auto& pollfd : pollfds) {
-
     if (pollfd.revents & POLLIN || pollfd.revents & POLLERR || pollfd.revents & POLLHUP) {
       const auto& iter = d_readCallbacks.find(pollfd.fd);
       if (iter != d_readCallbacks.end()) {
         iter->d_callback(iter->d_fd, iter->d_parameter);
+        count++;
       }
     }
 
@@ -158,12 +158,13 @@ int PollFDMultiplexer::run(struct timeval* now, int timeout)
       const auto& iter = d_writeCallbacks.find(pollfd.fd);
       if (iter != d_writeCallbacks.end()) {
         iter->d_callback(iter->d_fd, iter->d_parameter);
+        count++;
       }
     }
   }
 
   d_inrun = false;
-  return ret;
+  return count;
 }
 
 #if 0
index 76ebdb1e0778dcc74cf74886f4fae469b0f644c3..9e239c3aad7b40d94e35b7656f92a2aa72b69b43 100644 (file)
@@ -181,12 +181,13 @@ int PortsFDMultiplexer::run(struct timeval* now, int timeout)
   }
 
   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) {
       const auto& iter = d_readCallbacks.find(d_pevents[n].portev_object);
       if (iter != d_readCallbacks.end()) {
         iter->d_callback(iter->d_fd, iter->d_parameter);
+        count++;
         if (d_readCallbacks.count(d_pevents[n].portev_object) && port_associate(d_portfd, PORT_SOURCE_FD, d_pevents[n].portev_object, d_writeCallbacks.count(d_pevents[n].portev_object) ? POLLIN | POLLOUT : POLLIN, 0) < 0) {
           throw FDMultiplexerException("Unable to add fd back to ports (read): " + stringerror());
         }
@@ -196,6 +197,7 @@ int PortsFDMultiplexer::run(struct timeval* now, int timeout)
       const auto& iter = d_writeCallbacks.find(d_pevents[n].portev_object);
       if (iter != d_writeCallbacks.end()) {
         iter->d_callback(iter->d_fd, iter->d_parameter);
+        count++;
         if (d_writeCallbacks.count(d_pevents[n].portev_object) && port_associate(d_portfd, PORT_SOURCE_FD, d_pevents[n].portev_object, d_readCallbacks.count(d_pevents[n].portev_object) ? POLLIN | POLLOUT : POLLOUT, 0) < 0) {
           throw FDMultiplexerException("Unable to add fd back to ports (write): " + stringerror());
         }
@@ -204,7 +206,7 @@ int PortsFDMultiplexer::run(struct timeval* now, int timeout)
   }
 
   d_inrun = false;
-  return numevents;
+  return count;
 }
 
 #if 0
index 08be6a3882543b6695b5273378eb2555379be927..9b07838faac742d96bfc6499a604dcd279465de8 100644 (file)
@@ -258,7 +258,7 @@ BOOST_AUTO_TEST_CASE(test_MPlexer_ReadAndWrite)
   BOOST_CHECK_EQUAL(readyFDs.at(0), sockets[0]);
 
   auto ready = mplexer->run(&now, 100);
-  BOOST_CHECK_EQUAL(ready, 1);
+  BOOST_CHECK_EQUAL(ready, 2);
   BOOST_CHECK_EQUAL(readCBCalled, true);
   BOOST_CHECK_EQUAL(writeCBCalled, true);