From 881088fc0341608999b30d8d06573b86f37daa42 Mon Sep 17 00:00:00 2001 From: Yedidya Feldblum Date: Fri, 5 Jan 2018 14:23:31 -0800 Subject: [PATCH] Synchronized::exchange Summary: [Folly] `Synchronized::exchange`, for assigning a new value and returning the old value. (Note: this ignores all push blocking failures!) Differential Revision: D6653482 fbshipit-source-id: 68f4bd330bc2cf37bb92aff98b8ce3221334112e --- folly/Synchronized.h | 9 +++++++++ folly/test/SynchronizedTest.cpp | 4 ++++ folly/test/SynchronizedTestLib-inl.h | 10 ++++++++++ 3 files changed, 23 insertions(+) diff --git a/folly/Synchronized.h b/folly/Synchronized.h index 094dcdf0..7b016a14 100644 --- a/folly/Synchronized.h +++ b/folly/Synchronized.h @@ -691,6 +691,15 @@ struct Synchronized : public SynchronizedBase< swap(datum_, rhs); } + /** + * Assign another datum and return the original value. Recommended + * because it keeps the mutex held only briefly. + */ + T exchange(T&& rhs) { + swap(rhs); + return std::move(rhs); + } + /** * Copies datum to a given target. */ diff --git a/folly/test/SynchronizedTest.cpp b/folly/test/SynchronizedTest.cpp index e68fb5e4..c4735c2e 100644 --- a/folly/test/SynchronizedTest.cpp +++ b/folly/test/SynchronizedTest.cpp @@ -98,6 +98,10 @@ TYPED_TEST(SynchronizedTest, InPlaceConstruction) { testInPlaceConstruction(); } +TYPED_TEST(SynchronizedTest, Exchange) { + testExchange(); +} + template class SynchronizedTimedTest : public testing::Test {}; diff --git a/folly/test/SynchronizedTestLib-inl.h b/folly/test/SynchronizedTestLib-inl.h index 27b5d0d3..f588f99d 100644 --- a/folly/test/SynchronizedTestLib-inl.h +++ b/folly/test/SynchronizedTestLib-inl.h @@ -877,5 +877,15 @@ template void testInPlaceConstruction() { // This won't compile without in_place folly::Synchronized a(folly::in_place, 5, "a"); } + +template +void testExchange() { + std::vector input = {1, 2, 3}; + folly::Synchronized, Mutex> v(input); + std::vector next = {4, 5, 6}; + auto prev = v.exchange(std::move(next)); + EXPECT_EQ((std::vector{1, 2, 3}), prev); + EXPECT_EQ((std::vector{4, 5, 6}), v.copy()); +} } // namespace sync_tests } // namespace folly -- 2.34.1