From: Otto Date: Wed, 27 Jan 2021 12:36:55 +0000 (+0100) Subject: Fix race in registerAllStats() by making sure it only returns if the map X-Git-Tag: dnsdist-1.6.0-alpha2~47^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bfddf1e55e9b78cc34935aeccb68e87ae2b7229d;p=thirdparty%2Fpdns.git Fix race in registerAllStats() by making sure it only returns if the map has been fully initialized. If another thread is busy initing, we wait a bit. So it's safe to call getAllStatsMap() after registerAllStats() returns. Fixes #10021 --- diff --git a/pdns/rec_channel_rec.cc b/pdns/rec_channel_rec.cc index dce7a12fe5..72192b2b90 100644 --- a/pdns/rec_channel_rec.cc +++ b/pdns/rec_channel_rec.cc @@ -1041,9 +1041,14 @@ extern ResponseStats g_rs; void registerAllStats() { - static std::atomic_flag s_init = ATOMIC_FLAG_INIT; - if(s_init.test_and_set()) + static std::mutex s_lock; + static bool s_inited = false; + + std::lock_guard lock(s_lock); + + if (s_inited) { return; + } addGetStat("questions", &g_stats.qcounter); addGetStat("ipv6-questions", &g_stats.ipv6qcounter); @@ -1247,6 +1252,8 @@ void registerAllStats() const std::string name = "ecs-v6-response-bits-" + std::to_string(idx + 1); addGetStat(name, &(SyncRes::s_ecsResponsesBySubnetSize6.at(idx))); } + + s_inited = true; } void doExitGeneric(bool nicely) diff --git a/pdns/ws-recursor.cc b/pdns/ws-recursor.cc index 6481c7cbd4..a6760bc3c8 100644 --- a/pdns/ws-recursor.cc +++ b/pdns/ws-recursor.cc @@ -984,7 +984,6 @@ RecursorWebServer::RecursorWebServer(FDMultiplexer* fdm) registerAllStats(); #if CHECK_PROMETHEUS_METRICS - // There is a race here if another thread already called registerAllStats(); but it is not ready yet validatePrometheusMetrics(); #endif