diff --git a/src/threading/Manager.cc b/src/threading/Manager.cc index 1b6cb551e2..3bb8dbff3b 100644 --- a/src/threading/Manager.cc +++ b/src/threading/Manager.cc @@ -82,7 +82,11 @@ double Manager::NextTimestamp(double* network_time) { MsgThread* t = *i; - if ( (*i)->MightHaveOut() && ! t->Killed() ) + if ( ( (*i)->MightHaveOut() && ! t->Killed() ) // there might be something in the queue + // Workaround: when running without network source, and without any communication, + // timer_manager is always 1. Hence the previous if will never trigger heartbeats + // In this case, we still have to check process our threads from time to time. + || ( timer_mgr->Time() == 1.0 && random() % 10000 == 0 ) ) return timer_mgr->Time(); } diff --git a/src/threading/Queue.h b/src/threading/Queue.h index c4f2bfab00..5c1ddfd28e 100644 --- a/src/threading/Queue.h +++ b/src/threading/Queue.h @@ -63,11 +63,12 @@ public: /** * Returns true if the next Get() operation might succeed. This * function may occasionally return a value not indicating the actual - * state, but won't do so very often. Occasionally we also return a - * true unconditionally to avoid a deadlock when both pointers happen - * to be equal even though there's stuff queued. + * state, but won't do so very often. Note that this means that it can + * consistently return false even if there is something in the Queue. + * You have to check real queue status from time to time to be sure that + * it is empty. */ - bool MaybeReady() { return (read_ptr != write_ptr) || (random() % 10000 == 0); } + bool MaybeReady() { return (read_ptr != write_ptr); } /** Wake up the reader if it's currently blocked for input. This is primarily to give it a chance to check termination quickly.