From f73841594489716d100e380f8197803dd64b749f Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 7 May 2019 11:37:10 +0200 Subject: [PATCH] Do not busy loop if we get lots of notifies. Also rewrite main slave loop to use a timed wait for the semaphore. --- pdns/communicator.cc | 36 +++++++++--------------------------- pdns/unix_semaphore.cc | 6 ++++++ pdns/utility.hh | 3 +++ 3 files changed, 18 insertions(+), 27 deletions(-) diff --git a/pdns/communicator.cc b/pdns/communicator.cc index 709b8d05f..3e2ce98bb 100644 --- a/pdns/communicator.cc +++ b/pdns/communicator.cc @@ -113,37 +113,19 @@ void CommunicatorClass::mainloop(void) d_tickinterval=::arg().asNum("slave-cycle-interval"); makeNotifySockets(); - int rc; - time_t next, tick; - - for(;;) { + 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; - while(time(0) < next) { - rc=d_any_sem.tryWait(); + time_t tick = doNotifications(); // this processes any notification acknowledgements and actually send out our own notifications + tick = min(tick, d_tickinterval); + struct timespec abs_time = {.tv_sec = time(0) + tick, .tv_nsec = 0}; + + // Wait for a post for a max time. We might get EINTR, oh well + d_any_sem.timedWait(abs_time); - if(rc) { - bool extraSlaveRefresh = false; - Utility::sleep(1); - { - Lock l(&d_lock); - if (d_tocheck.size()) - extraSlaveRefresh = true; - } - if (extraSlaveRefresh) - slaveRefresh(&P); - } - else { - break; // something happened - } - // this gets executed at least once every second - doNotifications(); + while (d_any_sem.tryWait() == 0) { + // eat up remaining posts, will do next iteration shortly } } } diff --git a/pdns/unix_semaphore.cc b/pdns/unix_semaphore.cc index a4b25b6dd..bac933c0e 100644 --- a/pdns/unix_semaphore.cc +++ b/pdns/unix_semaphore.cc @@ -168,6 +168,12 @@ int Semaphore::wait() while (ret == -1 && errno == EINTR); return ret; } + +int Semaphore::timedWait(const struct timespec& abs_timeout) +{ + return sem_timedwait(m_pSemaphore, &abs_timeout); +} + int Semaphore::tryWait() { return sem_trywait(m_pSemaphore); diff --git a/pdns/utility.hh b/pdns/utility.hh index 024fc089f..30ea93230 100644 --- a/pdns/utility.hh +++ b/pdns/utility.hh @@ -78,6 +78,9 @@ public: //! Waits for a semaphore. int wait( void ); + //! Waits for a semaphore with a timeout + int timedWait(const struct timespec &abs_timeout); + //! Tries to wait for a semaphore. int tryWait( void ); -- 2.49.0