From: Miod Vallat Date: Thu, 6 Nov 2025 07:10:58 +0000 (+0100) Subject: Use a condition variable to signal the checker thread. X-Git-Tag: auth-5.1.0~7^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=86ede2609eb313ebca3084500bc1038d9e22b91c;p=thirdparty%2Fpdns.git Use a condition variable to signal the checker thread. Signed-off-by: Miod Vallat --- diff --git a/pdns/lua-record.cc b/pdns/lua-record.cc index 76e616e56e..a33174bed2 100644 --- a/pdns/lua-record.cc +++ b/pdns/lua-record.cc @@ -1,17 +1,19 @@ -#include +#include +#include +#include +#include #include #include -#include +#include +#include +#include #include +#include #include #include -#include -#include -#include + #include "misc.hh" #include "qtype.hh" -#include -#include #include "version.hh" #include "ext/luawrapper/include/LuaContext.hpp" #include "lock.hh" @@ -245,13 +247,13 @@ private: std::chrono::system_clock::time_point checkStart = std::chrono::system_clock::now(); std::vector> results; std::vector toDelete; - time_t interval{g_luaHealthChecksInterval}; { // make sure there's no insertion auto statuses = d_statuses.read_lock(); for (auto& it: *statuses) { auto& desc = it.first; auto& state = it.second; + time_t interval{g_luaHealthChecksInterval}; time_t checkInterval{0}; auto lastAccess = std::chrono::system_clock::from_time_t(state->lastAccess); @@ -301,10 +303,15 @@ private: // set thread name again, in case std::async surprised us by doing work in this thread setThreadName("pdns/luaupcheck"); - // Only sleep for 1 second here, even if the health check interval is - // larger, in case we get new entries to process in d_statuses in the - // meantime. - std::this_thread::sleep_for(std::chrono::seconds(1)); + // Wait for at most one complete check interval, but allow an earlier + // wakeup in case more work is being put in d_statuses. + { + std::unique_lock lock(d_mutex); + auto sleepTime = std::chrono::seconds(g_luaHealthChecksInterval) - (std::chrono::system_clock::now() - checkStart); + if (sleepTime > std::chrono::seconds::zero()) { + d_condvar.wait_until(lock, std::chrono::system_clock::now() + sleepTime); + } + } } } @@ -314,6 +321,9 @@ private: std::unique_ptr d_checkerThread; std::atomic_flag d_checkerThreadStarted; + std::mutex d_mutex; // used with the condition variable below + std::condition_variable d_condvar; + void setStatus(const CheckDesc& cd, bool status) { auto statuses = d_statuses.write_lock(); @@ -387,10 +397,14 @@ int IsUpOracle::isUp(const CheckDesc& cd) (*statuses)[cd] = std::make_unique(now); } } - // Now that we have given it work to do, make sure the checker thread runs. + // Now that we have given it work to do, make sure the checker thread runs, + // and notify it if it had already been running. if (!d_checkerThreadStarted.test_and_set()) { d_checkerThread = std::make_unique([this] { return checkThread(); }); } + else { + d_condvar.notify_all(); + } // If explicitly asked to fail on incomplete checks, report this (as // a negative value). static const std::string foic{"failOnIncompleteCheck"};