From abb81c353de037fb418a04b4281cf2c82c9c0ccb Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 14 Feb 2023 09:33:10 -0500 Subject: [PATCH] fixed race condition --- libi2pd/Profiling.cpp | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 2dafe8ca..4f032326 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include "Base.h" @@ -22,6 +23,7 @@ namespace data { static i2p::fs::HashedStorage g_ProfilesStorage("peerProfiles", "p", "profile-", "txt"); static std::unordered_map > g_Profiles; + static std::mutex g_ProfilesMutex; static boost::posix_time::ptime GetTime () { @@ -213,11 +215,15 @@ namespace data std::shared_ptr GetRouterProfile (const IdentHash& identHash) { - auto it = g_Profiles.find (identHash); - if (it != g_Profiles.end ()) - return it->second; + { + std::unique_lock l(g_ProfilesMutex); + auto it = g_Profiles.find (identHash); + if (it != g_Profiles.end ()) + return it->second; + } auto profile = std::make_shared (); profile->Load (identHash); // if possible + std::unique_lock l(g_ProfilesMutex); g_Profiles.emplace (identHash, profile); return profile; } @@ -231,6 +237,7 @@ namespace data void PersistProfiles () { auto ts = GetTime (); + std::unique_lock l(g_ProfilesMutex); for (auto it = g_Profiles.begin (); it != g_Profiles.end ();) { if ((ts - it->second->GetLastUpdateTime ()).total_seconds () > PEER_PROFILE_PERSIST_INTERVAL) @@ -247,6 +254,7 @@ namespace data void SaveProfiles () { auto ts = GetTime (); + std::unique_lock l(g_ProfilesMutex); for (auto it: g_Profiles) if (it.second->IsUpdated () && (ts - it.second->GetLastUpdateTime ()).total_seconds () < PEER_PROFILE_EXPIRATION_TIMEOUT*3600) it.second->Save (it.first); @@ -255,14 +263,17 @@ namespace data void DeleteObsoleteProfiles () { - auto ts = GetTime (); - for (auto it = g_Profiles.begin (); it != g_Profiles.end ();) - { - if ((ts - it->second->GetLastUpdateTime ()).total_seconds () >= PEER_PROFILE_EXPIRATION_TIMEOUT*3600) - it = g_Profiles.erase (it); - else - it++; - } + { + auto ts = GetTime (); + std::unique_lock l(g_ProfilesMutex); + for (auto it = g_Profiles.begin (); it != g_Profiles.end ();) + { + if ((ts - it->second->GetLastUpdateTime ()).total_seconds () >= PEER_PROFILE_EXPIRATION_TIMEOUT*3600) + it = g_Profiles.erase (it); + else + it++; + } + } struct stat st; std::time_t now = std::time(nullptr);