From: Maged Michael <magedmichael@fb.com> Date: Sat, 16 Dec 2017 17:48:36 +0000 (-0800) Subject: UnboundedQueue: Fix advanceHead X-Git-Tag: v2017.12.18.00~3 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=124efa238dc51b331457c940e17aa9cb7c47a92e;p=folly.git 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 --- 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); }