From 07116a378d6f8b4cb66c81a39447ecd6f6bbe826 Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Sat, 8 Aug 2026 17:44:55 -0400 Subject: [PATCH] remove remaining mutex locking, this is dangerous but necessary so metrics never causes deadlock; --- .../network/TrafficNetwork.MetricsLogging.cpp | 43 +++++-------------- 1 file changed, 11 insertions(+), 32 deletions(-) diff --git a/src/fne/network/TrafficNetwork.MetricsLogging.cpp b/src/fne/network/TrafficNetwork.MetricsLogging.cpp index 826efbf2..75cab1c5 100644 --- a/src/fne/network/TrafficNetwork.MetricsLogging.cpp +++ b/src/fne/network/TrafficNetwork.MetricsLogging.cpp @@ -301,8 +301,8 @@ namespace { } }; - static std::mutex g_sqliteWriterStatesMutex; - static std::unordered_map> g_sqliteWriterStates; + static std::atomic g_sqliteWriterState; + static std::shared_ptr g_sqliteWriterStateHolder; // --------------------------------------------------------------------------- // Global Functions @@ -724,20 +724,9 @@ namespace { if (network == nullptr) return; - std::shared_ptr state; - { - std::unique_lock stateLock(g_sqliteWriterStatesMutex, std::try_to_lock); - if (!stateLock.owns_lock()) { - LogError(LOG_MASTER, "SQLite metrics could not acquire state lock!"); - return; - } - - auto it = g_sqliteWriterStates.find(network); - if (it == g_sqliteWriterStates.end() || it->second == nullptr) { - return; - } - - state = it->second; + SQLiteWriterState* state = g_sqliteWriterState.load(std::memory_order_acquire); + if (state == nullptr) { + return; } size_t queueDepth = 0U; @@ -922,9 +911,8 @@ void TrafficNetwork::MetricsLogging::initialize(TrafficNetwork* network) // initialize the SQLite writer thread if the database is available if (network->m_sqliteDB != nullptr) { - std::unique_lock lock(g_sqliteWriterStatesMutex); - auto it = g_sqliteWriterStates.find(network); - if (it == g_sqliteWriterStates.end()) { + SQLiteWriterState* existingState = g_sqliteWriterState.load(std::memory_order_acquire); + if (existingState == nullptr) { auto state = std::make_shared(); if (!prepareStatements(network->m_sqliteDB, state->statements)) { LogError(LOG_MASTER, "Failed to prepare SQLite metrics statements: %s", sqlite3_errmsg(network->m_sqliteDB)); @@ -951,7 +939,9 @@ void TrafficNetwork::MetricsLogging::initialize(TrafficNetwork* network) } state->workerStarted.store(true, std::memory_order_release); - g_sqliteWriterStates.emplace(network, std::move(state)); + SQLiteWriterState* rawState = state.get(); + g_sqliteWriterStateHolder = std::move(state); + g_sqliteWriterState.store(rawState, std::memory_order_release); } } } @@ -964,18 +954,7 @@ void TrafficNetwork::MetricsLogging::finalize(TrafficNetwork* network) if (network == nullptr) return; - std::shared_ptr state; - - // scope is intentional - { - std::unique_lock lock(g_sqliteWriterStatesMutex); - auto it = g_sqliteWriterStates.find(network); - if (it != g_sqliteWriterStates.end()) { - state = std::move(it->second); - g_sqliteWriterStates.erase(it); - } - } - + SQLiteWriterState* state = g_sqliteWriterState.load(std::memory_order_acquire); if (state != nullptr) { state->stopRequested.store(true, std::memory_order_release);