mirror of
https://github.com/kiwix/libkiwix.git
synced 2025-06-26 10:11:30 +00:00
Add a template specialization for ConcurrentCache storing shared_ptr
When ConcurrentCache store a shared_ptr we may have shared_ptr in used while the ConcurrentCache has drop it. When we "recreate" a value to put in the cache, we don't want to recreate it, but copying the shared_ptr in use. To do so we use a (unlimited) store of weak_ptr (aka `WeakStore`) Every created shared_ptr added to the cache has a weak_ptr ref also stored in the WeakStore, and we check the WeakStore before creating the value.
This commit is contained in:
@ -107,3 +107,24 @@ TEST(ConcurrentCacheTest, handleException) {
|
||||
EXPECT_EQ(val, 888);
|
||||
}
|
||||
|
||||
TEST(ConcurrentCacheTest, weakPtr) {
|
||||
kiwix::ConcurrentCache<int, std::shared_ptr<int>> cache(1);
|
||||
auto refValue = cache.getOrPut(7, []() { return std::make_shared<int>(777); });
|
||||
EXPECT_EQ(*refValue, 777);
|
||||
EXPECT_EQ(refValue.use_count(), 2);
|
||||
|
||||
// This will drop shared(777) from the cache
|
||||
cache.getOrPut(8, []() { return std::make_shared<int>(888); });
|
||||
EXPECT_EQ(refValue.use_count(), 1);
|
||||
|
||||
// We must get the shared value from the weakPtr we have
|
||||
EXPECT_NO_THROW(cache.getOrPut(7, []() { throw std::runtime_error("oups"); return nullptr; }));
|
||||
EXPECT_EQ(refValue.use_count(), 2);
|
||||
|
||||
// Drop all ref
|
||||
cache.getOrPut(8, []() { return std::make_shared<int>(888); });
|
||||
refValue.reset();
|
||||
|
||||
// Be sure we call the construction function
|
||||
EXPECT_THROW(cache.getOrPut(7, []() { throw std::runtime_error("oups"); return nullptr; }), std::runtime_error);
|
||||
}
|
||||
|
Reference in New Issue
Block a user