Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions readerwriterqueue.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ©2013-2020 Cameron Desrochers.
// ©2013-2020 Cameron Desrochers.
// Distributed under the simplified BSD license (see the license file that
// should have come with this header).

Expand Down Expand Up @@ -619,6 +619,13 @@ class MOODYCAMEL_MAYBE_ALIGN_TO_CACHELINE ReaderWriterQueue
newBlock->tail = newBlock->localTail = 1;

newBlock->next = tailBlock_->next.load();

// Publish all writes to *newBlock before it becomes reachable via either
// tailBlock_->next (walked by size_approx() and other chain traversals)
// or tailBlock itself (used by try_dequeue). Without this fence, on
// weakly-ordered architectures (e.g. AArch64) a reader could observe the
// updated `next` pointer before seeing newBlock's initialized fields.
fence(memory_order_release);
tailBlock_->next = newBlock;

// Might be possible for the dequeue thread to see the new tailBlock->next
Expand All @@ -627,7 +634,6 @@ class MOODYCAMEL_MAYBE_ALIGN_TO_CACHELINE ReaderWriterQueue
// case where it could try to read the next is if it's already at the tailBlock,
// and it won't advance past tailBlock in any circumstance).

fence(memory_order_release);
tailBlock = newBlock;
}
else if (canAlloc == CannotAlloc) {
Expand Down