From 124efa238dc51b331457c940e17aa9cb7c47a92e Mon Sep 17 00:00:00 2001 From: Maged Michael Date: Sat, 16 Dec 2017 09:48:36 -0800 Subject: [PATCH] UnboundedQueue: Fix advanceHead Summary: Without the fix multiple consumers may update head concurrently and cause it to lag. If this persists until the destruction time of the queue, some segments may be incorrectly retired twice. The fix is to wait for head to advance to the current segment first before advancing head to the next segment. Reviewed By: djwatson Differential Revision: D6588135 fbshipit-source-id: 3e916441bff5ad3f27de418601990c59a0b89bc2 --- folly/concurrency/UnboundedQueue.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/folly/concurrency/UnboundedQueue.h b/folly/concurrency/UnboundedQueue.h index 1d9e5cb4..77bc5b9f 100644 --- a/folly/concurrency/UnboundedQueue.h +++ b/folly/concurrency/UnboundedQueue.h @@ -500,6 +500,13 @@ class UnboundedQueue { auto deadline = std::chrono::steady_clock::time_point::max(); Segment* next = tryGetNextSegmentUntil(s, deadline); DCHECK(next != nullptr); + while (head() != s) { + // Wait for head to advance to the current segment first before + // advancing head to the next segment. Otherwise, a lagging + // consumer responsible for advancing head from an earlier + // segment may incorrectly set head back. + asm_volatile_pause(); + } setHead(next); reclaimSegment(s); } -- 2.34.1