From 5cecffd34a17f1a9c0e58b0cd0fa36919e6a2069 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Tue, 31 Aug 2021 22:13:06 +0200 Subject: Fixed a race in bucket open/create logic If two requests were sufficiently close, they could end up trying to initialize buckets twice which is not a good idea --- zenserver/cache/structuredcachestore.cpp | 34 ++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'zenserver/cache/structuredcachestore.cpp') diff --git a/zenserver/cache/structuredcachestore.cpp b/zenserver/cache/structuredcachestore.cpp index 140ff1853..a07fccf98 100644 --- a/zenserver/cache/structuredcachestore.cpp +++ b/zenserver/cache/structuredcachestore.cpp @@ -581,13 +581,20 @@ ZenCacheDiskLayer::Get(std::string_view InBucket, const zen::IoHash& HashKey, Ze zen::RwLock::ExclusiveLockScope _(m_Lock); - auto It = m_Buckets.try_emplace(std::string(InBucket), m_CasStore); - Bucket = &It.first->second; + if (auto it = m_Buckets.find(std::string(InBucket)); it != m_Buckets.end()) + { + Bucket = &it->second; + } + else + { + auto It = m_Buckets.try_emplace(std::string(InBucket), m_CasStore); + Bucket = &It.first->second; - std::filesystem::path BucketPath = m_RootDir; - BucketPath /= std::string(InBucket); + std::filesystem::path BucketPath = m_RootDir; + BucketPath /= std::string(InBucket); - Bucket->OpenOrCreate(BucketPath.c_str()); + Bucket->OpenOrCreate(BucketPath.c_str()); + } } ZEN_ASSERT(Bucket != nullptr); @@ -617,13 +624,20 @@ ZenCacheDiskLayer::Put(std::string_view InBucket, const zen::IoHash& HashKey, co zen::RwLock::ExclusiveLockScope _(m_Lock); - auto It = m_Buckets.try_emplace(std::string(InBucket), m_CasStore); - Bucket = &It.first->second; + if (auto it = m_Buckets.find(std::string(InBucket)); it != m_Buckets.end()) + { + Bucket = &it->second; + } + else + { + auto It = m_Buckets.try_emplace(std::string(InBucket), m_CasStore); + Bucket = &It.first->second; - std::filesystem::path bucketPath = m_RootDir; - bucketPath /= std::string(InBucket); + std::filesystem::path bucketPath = m_RootDir; + bucketPath /= std::string(InBucket); - Bucket->OpenOrCreate(bucketPath.c_str()); + Bucket->OpenOrCreate(bucketPath.c_str()); + } } ZEN_ASSERT(Bucket != nullptr); -- cgit v1.2.3