Skip to content

Commit 0bcbf3d

Browse files
committed
Ensure cluster cache is properly clean in case of exception in constructor.
1 parent b6d9077 commit 0bcbf3d

File tree

3 files changed

+33
-16
lines changed

3 files changed

+33
-16
lines changed

src/fileimpl.cpp

+26-15
Original file line numberDiff line numberDiff line change
@@ -248,30 +248,41 @@ class Grouping
248248
const_cast<entry_index_t&>(m_endUserEntry) = getCountArticles();
249249
}
250250

251-
auto result = tmpDirentLookup.find('X', "listing/titleOrdered/v1");
252-
if (result.first) {
253-
mp_titleDirentAccessor = getTitleAccessorV1(result.second);
254-
}
251+
// Following code will may create cluster and we want to remove them from cache
252+
// if something goes wrong.
253+
try {
254+
auto result = tmpDirentLookup.find('X', "listing/titleOrdered/v1");
255+
if (result.first) {
256+
mp_titleDirentAccessor = getTitleAccessorV1(result.second);
257+
}
255258

256-
if (!mp_titleDirentAccessor) {
257-
if (!header.hasTitleListingV0()) {
258-
throw ZimFileFormatError("Zim file doesn't contain a title ordered index");
259+
if (!mp_titleDirentAccessor) {
260+
if (!header.hasTitleListingV0()) {
261+
throw ZimFileFormatError("Zim file doesn't contain a title ordered index");
262+
}
263+
offset_t titleOffset(header.getTitleIdxPos());
264+
zsize_t titleSize(sizeof(entry_index_type)*header.getArticleCount());
265+
mp_titleDirentAccessor = getTitleAccessor(titleOffset, titleSize, "Title index table");
266+
const_cast<bool&>(m_hasFrontArticlesIndex) = false;
259267
}
260-
offset_t titleOffset(header.getTitleIdxPos());
261-
zsize_t titleSize(sizeof(entry_index_type)*header.getArticleCount());
262-
mp_titleDirentAccessor = getTitleAccessor(titleOffset, titleSize, "Title index table");
263-
const_cast<bool&>(m_hasFrontArticlesIndex) = false;
264-
}
265-
m_byTitleDirentLookup.reset(new ByTitleDirentLookup(mp_titleDirentAccessor.get()));
268+
m_byTitleDirentLookup.reset(new ByTitleDirentLookup(mp_titleDirentAccessor.get()));
266269

267-
readMimeTypes();
270+
readMimeTypes();
271+
} catch (...) {
272+
dropCachedClusters();
273+
throw;
274+
}
268275
}
269276

270277
FileImpl::~FileImpl() {
271-
// We have to clean the global cache for our clusters.
278+
dropCachedClusters();
279+
}
280+
281+
void FileImpl::dropCachedClusters() const {
272282
getClusterCache().dropAll([=](const std::tuple<FileImpl*, cluster_index_type>& key) {return std::get<0>(key) == this;});
273283
}
274284

285+
275286
std::unique_ptr<IndirectDirentAccessor> FileImpl::getTitleAccessorV1(const entry_index_t idx)
276287
{
277288
auto dirent = mp_pathDirentAccessor->getDirent(idx);

src/fileimpl.h

+2
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ namespace zim
166166
explicit FileImpl(std::shared_ptr<FileCompound> zimFile);
167167
FileImpl(std::shared_ptr<FileCompound> zimFile, offset_t offset, zsize_t size);
168168

169+
void dropCachedClusters() const;
170+
169171
std::unique_ptr<IndirectDirentAccessor> getTitleAccessorV1(const entry_index_t idx);
170172
std::unique_ptr<IndirectDirentAccessor> getTitleAccessor(const offset_t offset, const zsize_t size, const std::string& name);
171173

test/archive.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ class ZimArchive: public testing::Test {
5050
zim::setClusterCacheMaxSize(CLUSTER_CACHE_SIZE);
5151
ASSERT_EQ(zim::getClusterCacheCurrentSize(), 0);
5252
}
53+
void TearDown() override {
54+
ASSERT_EQ(zim::getClusterCacheCurrentSize(), 0);
55+
}
5356
};
5457

5558
using TestContextImpl = std::vector<std::pair<std::string, std::string> >;
@@ -691,7 +694,8 @@ class CapturedStderr
691694
#define EXPECT_BROKEN_ZIMFILE(ZIMPATH, EXPECTED_STDERROR_TEXT) \
692695
CapturedStderr stderror; \
693696
EXPECT_FALSE(zim::validate(ZIMPATH, checksToRun)); \
694-
EXPECT_EQ(EXPECTED_STDERROR_TEXT, std::string(stderror)) << ZIMPATH;
697+
EXPECT_EQ(EXPECTED_STDERROR_TEXT, std::string(stderror)) << ZIMPATH; \
698+
ASSERT_EQ(zim::getClusterCacheCurrentSize(), 0);
695699

696700
#define TEST_BROKEN_ZIM_NAME(ZIMNAME, EXPECTED) \
697701
for(auto& testfile: getDataFilePath(ZIMNAME)) {EXPECT_BROKEN_ZIMFILE(testfile.path, EXPECTED)}

0 commit comments

Comments
 (0)