Skip to content

Commit 91afabf

Browse files
committed
Fix potential race condition on m_direntLookup initialization.
Reading and writing in the same time to a unique_ptr is not thread safe. We introduce a atomicBool to know if the unique_ptr has been initialized. Fix #945
1 parent 13f5aea commit 91afabf

File tree

2 files changed

+6
-3
lines changed

2 files changed

+6
-3
lines changed

src/fileimpl.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ class Grouping
191191
m_hasFrontArticlesIndex(true),
192192
m_startUserEntry(0),
193193
m_endUserEntry(0),
194+
m_direntLookupCreated(false),
194195
m_direntLookupSize(DIRENT_LOOKUP_CACHE_SIZE)
195196
{
196197
log_trace("read file \"" << zimFile->filename() << '"');
@@ -295,14 +296,15 @@ class Grouping
295296
// in the call stack.
296297
// 2. With `glibc` an exceptional execution of `std::call_once` doesn't
297298
// unlock the mutex associated with the `std::once_flag` object.
298-
if ( !m_direntLookup ) {
299+
if (!m_direntLookupCreated.load(std::memory_order_acquire)) {
299300
std::lock_guard<std::mutex> lock(m_direntLookupCreationMutex);
300301
if ( !m_direntLookup ) {
301302
if (m_direntLookupSize == 0) {
302303
m_direntLookup = std::make_unique<DirentLookup>(mp_pathDirentAccessor.get());
303304
} else {
304305
m_direntLookup = std::make_unique<FastDirentLookup>(mp_pathDirentAccessor.get(), m_direntLookupSize);
305306
}
307+
m_direntLookupCreated.store(true, std::memory_order_release);
306308
}
307309
}
308310
return *m_direntLookup;
@@ -804,8 +806,7 @@ bool checkTitleListing(const IndirectDirentAccessor& accessor, entry_index_type
804806
}
805807

806808
size_t FileImpl::get_dirent_lookup_cache_max_size() const {
807-
std::lock_guard<std::mutex> lock(m_direntLookupCreationMutex);
808-
if ( !m_direntLookup ) {
809+
if (!m_direntLookupCreated.load(std::memory_order_acquire)) {
809810
return m_direntLookupSize;
810811
} else {
811812
return m_direntLookup->getSize();

src/fileimpl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#ifndef ZIM_FILEIMPL_H
2323
#define ZIM_FILEIMPL_H
2424

25+
#include <atomic>
2526
#include <string>
2627
#include <vector>
2728
#include <memory>
@@ -79,6 +80,7 @@ namespace zim
7980
using FastDirentLookup = zim::FastDirentLookup<DirentLookupConfig>;
8081
mutable std::unique_ptr<DirentLookup> m_direntLookup;
8182
mutable std::mutex m_direntLookupCreationMutex;
83+
mutable std::atomic_bool m_direntLookupCreated;
8284
size_t m_direntLookupSize;
8385

8486

0 commit comments

Comments
 (0)