slots_[idx(ticket)].write(turn(ticket), value);
}
+ /// Perform a single write of an object of type T.
+ /// Writes can block iff a previous writer has not yet completed a write
+ /// for the same slot (before the most recent wrap-around).
+ /// Returns a Cursor pointing to the just-written T.
+ Cursor writeAndGetCursor(T& value) noexcept {
+ uint64_t ticket = ticket_.fetch_add(1);
+ slots_[idx(ticket)].write(turn(ticket), value);
+ return Cursor(ticket);
+ }
+
/// Read the value at the cursor.
/// Returns true if the read succeeded, false otherwise. If the return
/// value is false, dest is to be considered partially read and in an
EXPECT_TRUE(midvalue == 1 || midvalue == 2);
}
+TEST(LockFreeRingBuffer, cursorFromWrites) {
+ const int capacity = 3;
+ LockFreeRingBuffer<int> rb(capacity);
+
+ // Workaround for template deduction failure
+ auto (&cursorValue)(value<int, std::atomic>);
+
+ int val = 0xfaceb00c;
+ EXPECT_EQ(0, cursorValue(rb.writeAndGetCursor(val)));
+ EXPECT_EQ(1, cursorValue(rb.writeAndGetCursor(val)));
+ EXPECT_EQ(2, cursorValue(rb.writeAndGetCursor(val)));
+
+ // Check that rb is giving out actual cursors and not just
+ // pointing to the current slot.
+ EXPECT_EQ(3, cursorValue(rb.writeAndGetCursor(val)));
+}
+
} // namespace folly