summaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@online.no>2022-02-28 22:36:13 +0100
committerTor Egge <Tor.Egge@online.no>2022-02-28 22:36:13 +0100
commitf6c739624c5ec286fd66f6f7cb47e814bcc86378 (patch)
tree67e5761d881fe771129fe73f71d964adeb1d223a /vespalib
parent4fa7d094dfba8affcf7a557ced76cc8ef74004cd (diff)
Restore atomic thread fence in vespalib::GenerationHandler::incGeneration().
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/vespa/vespalib/util/generationhandler.cpp5
1 files changed, 5 insertions, 0 deletions
diff --git a/vespalib/src/vespa/vespalib/util/generationhandler.cpp b/vespalib/src/vespa/vespalib/util/generationhandler.cpp
index 5cee18108d6..a4b3dd6f5e6 100644
--- a/vespalib/src/vespa/vespalib/util/generationhandler.cpp
+++ b/vespalib/src/vespa/vespalib/util/generationhandler.cpp
@@ -179,10 +179,15 @@ GenerationHandler::incGeneration()
{
generation_t ngen = getNextGeneration();
+ // Make pending writes visible to other threads before checking for readers
+ // present in last generation.
+ std::atomic_thread_fence(std::memory_order_seq_cst);
auto last = _last.load(std::memory_order_relaxed);
if (last->getRefCount() == 0) {
// Last generation is unused, morph it to new generation. This is
// the typical case when no readers are present.
+ // Note: atomic thread fence above is needed to avoid stale data in
+ // reader
_generation = ngen;
last->_generation.store(ngen, std::memory_order_relaxed);
updateFirstUsedGeneration();