Separating slave and master comms threads can come later.
d_tickinterval=::arg().asNum("slave-cycle-interval");
makeNotifySockets();
- for (;;) {
+ for(;;) {
slaveRefresh(&P);
masterUpdateCheck(&P);
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};
+ time_t next = time(0) + tick;
- // Wait for a post for a max time. We might get EINTR, oh well
- d_any_sem.timedWait(abs_time);
+ 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 (d_any_sem.tryWait() == 0) {
- // eat up remaining posts, will do next iteration shortly
+ if (rc == std::cv_status::timeout) {
+ bool extraSlaveRefresh = false;
+ {
+ 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();
}
}
}
#include <pthread.h>
#include <string>
#include <semaphore.h>
+#include <condition_variable>
#include <queue>
#include <list>
#include <limits>
set<DNSName> d_inprogress;
Semaphore d_suck_sem;
- Semaphore d_any_sem;
+ std::condition_variable d_any_condvar;
+ std::mutex d_any_mutex;
time_t d_tickinterval;
set<DomainInfo> d_tocheck;
struct cmp {
void CommunicatorClass::notify(const DNSName &domain, const string &ip)
{
d_nq.add(domain, ip);
- d_any_sem.post();
+ d_any_condvar.notify_one();
}
}
d_tocheck.erase(di);
d_tocheck.insert(ours);
- d_any_sem.post(); // kick the loop!
+ d_any_condvar.notify_one(); // kick the loop!
}
void CommunicatorClass::addTrySuperMasterRequest(DNSPacket *p)
Lock l(&d_lock);
DNSPacket ours = *p;
if(d_potentialsupermasters.insert(ours).second)
- d_any_sem.post(); // kick the loop!
+ d_any_condvar.notify_one(); // kick the loop!
}
void CommunicatorClass::slaveRefresh(PacketHandler *P)
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);
//! 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 );