diff options
| author | Stefan Boberg <[email protected]> | 2021-08-31 22:13:06 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2021-08-31 22:13:06 +0200 |
| commit | 5cecffd34a17f1a9c0e58b0cd0fa36919e6a2069 (patch) | |
| tree | 6a55c4e13213d9d058828458f365152d8d2dd394 /zenserver/cache/structuredcachestore.cpp | |
| parent | Reordered flags to get better codegen for IsNull() (diff) | |
| download | zen-5cecffd34a17f1a9c0e58b0cd0fa36919e6a2069.tar.xz zen-5cecffd34a17f1a9c0e58b0cd0fa36919e6a2069.zip | |
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
Diffstat (limited to 'zenserver/cache/structuredcachestore.cpp')
| -rw-r--r-- | zenserver/cache/structuredcachestore.cpp | 34 |
1 files changed, 24 insertions, 10 deletions
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); |