UnboundedQueue: Fix advanceHead
authorMaged Michael <magedmichael@fb.com>
Sat, 16 Dec 2017 17:48:36 +0000 (09:48 -0800)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Sat, 16 Dec 2017 17:51:08 +0000 (09:51 -0800)
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

index 1d9e5cb4f6b9398a100a6253cbd929a60bd8823d..77bc5b9fa7d005dfb5f022608bffd1685fbfa115 100644 (file)
@@ -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);
   }