From 3d50e6522ee165886e293dc3fe49af3f0789d3a9 Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Tue, 30 Nov 2021 19:32:45 +0100 Subject: Fixed crash in cache tracker. --- zenserver/cache/cachetracking.cpp | 40 +++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'zenserver/cache/cachetracking.cpp') diff --git a/zenserver/cache/cachetracking.cpp b/zenserver/cache/cachetracking.cpp index 6a9b2f403..d1c99a597 100644 --- a/zenserver/cache/cachetracking.cpp +++ b/zenserver/cache/cachetracking.cpp @@ -49,22 +49,29 @@ public: Tracker->Track(HashKey); } - void SerializeSnapshot(CbObjectWriter& Cbo) + bool SerializeSnapshot(CbObjectWriter& Cbo) { + bool Serialized = false; RwLock::ExclusiveLockScope _(m_Lock); for (const auto& Kv : m_BucketMapping) { - Cbo.BeginArray(Kv.first); - m_Buckets[Kv.second]->SerializeSnapshotAndClear(Cbo); - Cbo.EndArray(); + if (m_Buckets[Kv.second]->Size()) + { + Cbo.BeginArray(Kv.first); + m_Buckets[Kv.second]->SerializeSnapshotAndClear(Cbo); + Cbo.EndArray(); + Serialized = true; + } } + + return Serialized; } private: struct BucketTracker { - RwLock Lock; + mutable RwLock Lock; tsl::robin_set AccessedKeys; void Track(const IoHash& HashKey) @@ -90,6 +97,12 @@ private: AccessedKeys.clear(); } + + size_t Size() const + { + RwLock::SharedLockScope _(Lock); + return AccessedKeys.size(); + } }; BucketTracker* GetBucket(const std::string& BucketName) @@ -198,15 +211,18 @@ struct ZenCacheTracker::Impl void SaveSnapshot() { CbObjectWriter Cbo; - m_CurrentSnapshot.SerializeSnapshot(Cbo); - IoBuffer SnapshotBuffer = Cbo.Save().GetBuffer().AsIoBuffer(); - const KeyStruct Key{.TimestampLittleEndian = ToNetworkOrder(GetCurrentCacheTimeStamp())}; - rocksdb::Slice KeySlice{(const char*)&Key, sizeof Key}; - rocksdb::Slice ValueSlice{(char*)SnapshotBuffer.Data(), SnapshotBuffer.Size()}; + if (m_CurrentSnapshot.SerializeSnapshot(Cbo)) + { + IoBuffer SnapshotBuffer = Cbo.Save().GetBuffer().AsIoBuffer(); + + const KeyStruct Key{.TimestampLittleEndian = ToNetworkOrder(GetCurrentCacheTimeStamp())}; + rocksdb::Slice KeySlice{(const char*)&Key, sizeof Key}; + rocksdb::Slice ValueSlice{(char*)SnapshotBuffer.Data(), SnapshotBuffer.Size()}; - rocksdb::WriteOptions Wo; - m_RocksDb->Put(Wo, KeySlice, ValueSlice); + rocksdb::WriteOptions Wo; + m_RocksDb->Put(Wo, KeySlice, ValueSlice); + } } void IterateSnapshots(std::function&& Callback) -- cgit v1.2.3