]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Slightly reduce contention around a pool's servers
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 12 Aug 2022 08:50:04 +0000 (10:50 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 12 Aug 2022 08:50:04 +0000 (10:50 +0200)
We only need to take the lock to get the shared pointer, as the
actual content is guaranteed not to change, so we do not need to
hold the lock while we iterate over the servers list to check
whether they are up, or what their current outstanding count is.

pdns/dnsdistdist/dnsdist-backend.cc

index e12dd77284f93a096c4fa1a1835e163b9a6fffbc..95ab0c4b4b24eca1a92a6cd75717fb3bbe71e687 100644 (file)
@@ -475,21 +475,32 @@ IDState* DownstreamState::getIDState(unsigned int& selectedID, int64_t& generati
 
 size_t ServerPool::countServers(bool upOnly)
 {
+  std::shared_ptr<ServerPolicy::NumberedServerVector> servers = nullptr;
+  {
+    auto lock = d_servers.read_lock();
+    servers = *lock;
+  }
+
   size_t count = 0;
-  auto servers = d_servers.read_lock();
-  for (const auto& server : **servers) {
+  for (const auto& server : *servers) {
     if (!upOnly || std::get<1>(server)->isUp() ) {
       count++;
     }
   }
+
   return count;
 }
 
 size_t ServerPool::poolLoad()
 {
+  std::shared_ptr<ServerPolicy::NumberedServerVector> servers = nullptr;
+  {
+    auto lock = d_servers.read_lock();
+    servers = *lock;
+  }
+
   size_t load = 0;
-  auto servers = d_servers.read_lock();
-  for (const auto& server : **servers) {
+  for (const auto& server : *servers) {
     size_t serverOutstanding = std::get<1>(server)->outstanding.load();
     load += serverOutstanding;
   }