From: Remi Gacogne Date: Thu, 5 Aug 2021 06:50:55 +0000 (+0200) Subject: Consistently return the number of ready events, not descriptor X-Git-Tag: dnsdist-1.7.0-alpha1~61^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c7a9f1b415f873568e8bd0839d1b272433e4558a;p=thirdparty%2Fpdns.git Consistently return the number of ready events, not descriptor 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. --- diff --git a/pdns/devpollmplexer.cc b/pdns/devpollmplexer.cc index c73c03d28f..b0c295862e 100644 --- a/pdns/devpollmplexer.cc +++ b/pdns/devpollmplexer.cc @@ -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 diff --git a/pdns/epollmplexer.cc b/pdns/epollmplexer.cc index dc060f1307..1be901da8e 100644 --- a/pdns/epollmplexer.cc +++ b/pdns/epollmplexer.cc @@ -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 diff --git a/pdns/mplexer.hh b/pdns/mplexer.hh index 6ea2e0ea85..b5742a8c48 100644 --- a/pdns/mplexer.hh +++ b/pdns/mplexer.hh @@ -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 */ diff --git a/pdns/pollmplexer.cc b/pdns/pollmplexer.cc index 924999c1b0..c9fdefb68b 100644 --- a/pdns/pollmplexer.cc +++ b/pdns/pollmplexer.cc @@ -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 diff --git a/pdns/portsmplexer.cc b/pdns/portsmplexer.cc index 76ebdb1e07..9e239c3aad 100644 --- a/pdns/portsmplexer.cc +++ b/pdns/portsmplexer.cc @@ -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 diff --git a/pdns/test-mplexer.cc b/pdns/test-mplexer.cc index 08be6a3882..9b07838faa 100644 --- a/pdns/test-mplexer.cc +++ b/pdns/test-mplexer.cc @@ -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);