Synchronized::exchange
authorYedidya Feldblum <yfeldblum@fb.com>
Fri, 5 Jan 2018 22:23:31 +0000 (14:23 -0800)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Fri, 5 Jan 2018 22:50:36 +0000 (14:50 -0800)
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
folly/test/SynchronizedTest.cpp
folly/test/SynchronizedTestLib-inl.h

index 094dcdf02af8e9e42fe7827396b780af620b79f8..7b016a1436bd5985232ef68ff35fc7df7645ee37 100644 (file)
@@ -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.
    */
index e68fb5e432c4a625b603d8d52caa2c1bd7c81902..c4735c2e9bbce2f0a0cd3a34409894614cbceb78 100644 (file)
@@ -98,6 +98,10 @@ TYPED_TEST(SynchronizedTest, InPlaceConstruction) {
   testInPlaceConstruction<TypeParam>();
 }
 
+TYPED_TEST(SynchronizedTest, Exchange) {
+  testExchange<TypeParam>();
+}
+
 template <class Mutex>
 class SynchronizedTimedTest : public testing::Test {};
 
index 27b5d0d3ed35761e5a219d02ae3bef40741d5750..f588f99dc9b9d27f4c1b1e5b8eced48a5485c69c 100644 (file)
@@ -877,5 +877,15 @@ template <class Mutex> void testInPlaceConstruction() {
   // This won't compile without in_place
   folly::Synchronized<NotCopiableNotMovable> a(folly::in_place, 5, "a");
 }
+
+template <class Mutex>
+void testExchange() {
+  std::vector<int> input = {1, 2, 3};
+  folly::Synchronized<std::vector<int>, Mutex> v(input);
+  std::vector<int> next = {4, 5, 6};
+  auto prev = v.exchange(std::move(next));
+  EXPECT_EQ((std::vector<int>{1, 2, 3}), prev);
+  EXPECT_EQ((std::vector<int>{4, 5, 6}), v.copy());
+}
 } // namespace sync_tests
 } // namespace folly