From: bert hubert Date: Fri, 5 Jun 2015 19:21:46 +0000 (+0200) Subject: make timeout a double, since we'd busy loop otherwise on sub-msec intervals, plus... X-Git-Tag: dnsdist-1.0.0-alpha1~248^2~78^2~19^2^2~9 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ce79dd66774e3a6a44b8d8b386a0b4d443b9a9e3;p=pdns make timeout a double, since we'd busy loop otherwise on sub-msec intervals, plus fix testcase which was actually a race condition. --- diff --git a/pdns/delaypipe.cc b/pdns/delaypipe.cc index d0798a532..046a90ef3 100644 --- a/pdns/delaypipe.cc +++ b/pdns/delaypipe.cc @@ -50,16 +50,18 @@ bool ObjectPipe::read(T* t) } template -int ObjectPipe::readTimeout(T* t, int msec) +int ObjectPipe::readTimeout(T* t, double msec) { T* ptr; - int ret = waitForData(d_fds[0], 0, 1000*msec); - if(ret <0) - unixDie("waiting for data in object pipe"); - if(ret == 0) - return -1; + if(msec != 0) { + int ret = waitForData(d_fds[0], 0, 1000*msec); + if(ret < 0) + unixDie("waiting for data in object pipe"); + if(ret == 0) + return -1; + } - ret = ::read(d_fds[0], &ptr, sizeof(ptr)); + int ret = ::read(d_fds[0], &ptr, sizeof(ptr)); if(ret < 0) unixDie("read"); @@ -97,31 +99,46 @@ DelayPipe::~DelayPipe() d_thread.join(); } + + template void DelayPipe::worker() { Combo c; for(;;) { - int ret = d_pipe.readTimeout(&c, 10); // XXXX NEEDS TO BE DYNAMIC - if(ret > 0) { // we got an object - d_work.insert(make_pair(c.when, c.what)); - } - else if(ret==0) { // timeout - - break; + double delay=-1; // infinite + struct timespec now; + if(!d_work.empty()) { + clock_gettime(CLOCK_MONOTONIC, &now); + delay=1000*tsdelta(d_work.begin()->first, now); + if(delay < 0) { + delay=0; // don't wait + } } - else { - // cout<<"Got a timeout"< 0) { // we got an object + d_work.insert(make_pair(c.when, c.what)); + } + else if(ret==0) { // EOF + break; + } + else { + ; + } + clock_gettime(CLOCK_MONOTONIC, &now); } - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); + tscomp cmp; + for(auto iter = d_work.begin() ; iter != d_work.end(); ) { // do the needful if(cmp(iter->first, now)) { iter->second(); d_work.erase(iter++); } - else break; + else { + break; + } } } } diff --git a/pdns/delaypipe.hh b/pdns/delaypipe.hh index cfc72e74b..80cca5906 100644 --- a/pdns/delaypipe.hh +++ b/pdns/delaypipe.hh @@ -23,7 +23,7 @@ public: ~ObjectPipe(); void write(T& t); bool read(T* t); // returns false on EOF - int readTimeout(T* t, int msec); // -1 is timeout, 0 is no data, 1 is data + int readTimeout(T* t, double msec); // -1 is timeout, 0 is no data, 1 is data void close(); private: int d_fds[2]; @@ -46,6 +46,11 @@ private: struct timespec when; }; + double tsdelta(const struct timespec& a, const struct timespec& b) // read as a-b + { + return 1.0*(a.tv_sec-b.tv_sec)+1.0*(a.tv_nsec-b.tv_nsec)/1000000000.0; + } + ObjectPipe d_pipe; struct tscomp { bool operator()(const struct timespec& a, const struct timespec& b) const diff --git a/pdns/test-delaypipe_hh.cc b/pdns/test-delaypipe_hh.cc index 94287a935..145adc4cb 100644 --- a/pdns/test-delaypipe_hh.cc +++ b/pdns/test-delaypipe_hh.cc @@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(test_delay_pipe) { for(; n < 10; ++n) { Work w{n}; - dp.submit(w, 1000); + dp.submit(w, 1200); } sleep(1); BOOST_CHECK_EQUAL(done, 5);