From: Otto Moerbeek Date: Fri, 10 May 2019 11:45:00 +0000 (+0200) Subject: Minimal fix to avoid busy looping. The condition_variable varant showed X-Git-Tag: rec-4.2.0-rc1~8^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=006adf321ad4af7b1681e617c73308c5b4e811c4;p=pdns Minimal fix to avoid busy looping. The condition_variable varant showed spurious failures on travis so go for the minimial fix. --- diff --git a/pdns/communicator.cc b/pdns/communicator.cc index 836f07e59..be8af6172 100644 --- a/pdns/communicator.cc +++ b/pdns/communicator.cc @@ -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 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 diff --git a/pdns/communicator.hh b/pdns/communicator.hh index d7d7178a7..c63534dc2 100644 --- a/pdns/communicator.hh +++ b/pdns/communicator.hh @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -206,8 +205,7 @@ private: set 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 d_tocheck; struct cmp { diff --git a/pdns/mastercommunicator.cc b/pdns/mastercommunicator.cc index 5d6c97459..048034749 100644 --- a/pdns/mastercommunicator.cc +++ b/pdns/mastercommunicator.cc @@ -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(); } diff --git a/pdns/slavecommunicator.cc b/pdns/slavecommunicator.cc index 50cf01c0b..190488faf 100644 --- a/pdns/slavecommunicator.cc +++ b/pdns/slavecommunicator.cc @@ -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)