aboutsummaryrefslogtreecommitdiff
path: root/zenserver/cache/structuredcachestore.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2021-08-31 22:13:06 +0200
committerStefan Boberg <[email protected]>2021-08-31 22:13:06 +0200
commit5cecffd34a17f1a9c0e58b0cd0fa36919e6a2069 (patch)
tree6a55c4e13213d9d058828458f365152d8d2dd394 /zenserver/cache/structuredcachestore.cpp
parentReordered flags to get better codegen for IsNull() (diff)
downloadzen-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.cpp34
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);