]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Minimal fix to avoid busy looping. The condition_variable varant showed 7790/head
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 10 May 2019 11:45:00 +0000 (13:45 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 10 May 2019 12:03:45 +0000 (14:03 +0200)
spurious failures on travis so go for the minimial fix.

pdns/communicator.cc
pdns/communicator.hh
pdns/mastercommunicator.cc
pdns/slavecommunicator.cc

index 836f07e59a18e33096de30f763d3b6a856d22ae4..be8af617239e08a44601ff8c92370d11f06875a9 100644 (file)
@@ -113,21 +113,24 @@ void CommunicatorClass::mainloop(void)
     d_tickinterval=::arg().asNum("slave-cycle-interval");
     makeNotifySockets();
 
+    int rc;
+    time_t next, tick;
+
     for(;;) {
       slaveRefresh(&P);
       masterUpdateCheck(&P);
+      tick=doNotifications(); // this processes any notification acknowledgements and actually send out our own notifications
+      
+      tick = min (tick, d_tickinterval); 
+      
+      next=time(0)+tick;
 
-      time_t tick = doNotifications(); // this processes any notification acknowledgements and actually send out our own notifications
-      tick = min(tick, d_tickinterval);
-      time_t next = time(0) + tick;
-
-      while (time(0) < next) {
-        std::unique_lock<std::mutex> lk(d_any_mutex);
-        auto rc = d_any_condvar.wait_for(lk, std::chrono::seconds(1));
-        lk.unlock();
+      while(time(0) < next) {
+        rc=d_any_sem.tryWait();
 
-        if (rc == std::cv_status::timeout) {
+        if(rc) {
           bool extraSlaveRefresh = false;
+          Utility::sleep(1);
           {
             Lock l(&d_lock);
             if (d_tocheck.size())
@@ -137,6 +140,9 @@ void CommunicatorClass::mainloop(void)
             slaveRefresh(&P);
         }
         else {
+          // eat up extra posts to avoid busy looping if many posts were done
+          while (d_any_sem.tryWait() == 0) {
+          }
           break; // something happened
         }
         // this gets executed at least once every second
index d7d7178a7fea0f0c5cc04a94d5ebb07ec5fd44c5..c63534dc232b5fa709eba136905c9bfcde208645 100644 (file)
@@ -25,7 +25,6 @@
 #include <pthread.h>
 #include <string>
 #include <semaphore.h>
-#include <condition_variable>
 #include <queue>
 #include <list>
 #include <limits>
@@ -206,8 +205,7 @@ private:
   set<DNSName> d_inprogress;
   
   Semaphore d_suck_sem;
-  std::condition_variable d_any_condvar;
-  std::mutex d_any_mutex;
+  Semaphore d_any_sem;
   time_t d_tickinterval;
   set<DomainInfo> d_tocheck;
   struct cmp {
index 5d6c97459b4584da0285fdd46a3e3faf87dd9a68..04803474994a64e63d7294265b30260d6ed0a768 100644 (file)
@@ -303,5 +303,5 @@ void CommunicatorClass::makeNotifySockets()
 void CommunicatorClass::notify(const DNSName &domain, const string &ip)
 {
   d_nq.add(domain, ip);
-  d_any_condvar.notify_one();
+  d_any_sem.post();
 }
index 50cf01c0b36dff3886d76687282489682ca6f774..190488faf5d74c2493ba6937597bd806c6695bb5 100644 (file)
@@ -727,7 +727,7 @@ void CommunicatorClass::addSlaveCheckRequest(const DomainInfo& di, const ComboAd
   }
   d_tocheck.erase(di);
   d_tocheck.insert(ours);
-  d_any_condvar.notify_one(); // kick the loop!
+  d_any_sem.post(); // kick the loop!
 }
 
 void CommunicatorClass::addTrySuperMasterRequest(DNSPacket *p)
@@ -735,7 +735,7 @@ void CommunicatorClass::addTrySuperMasterRequest(DNSPacket *p)
   Lock l(&d_lock);
   DNSPacket ours = *p;
   if(d_potentialsupermasters.insert(ours).second)
-    d_any_condvar.notify_one(); // kick the loop!
+    d_any_sem.post(); // kick the loop!
 }
 
 void CommunicatorClass::slaveRefresh(PacketHandler *P)