• Emanuele Altieri's avatar
    The Latch synchronization class · dc7ba0b5
    Emanuele Altieri authored
    Summary:
    Similar to std::latch (C++20) but with timed waits:
    https://en.cppreference.com/w/cpp/thread/latch
    
    The latch class is a downward counter which can be used to synchronize
    threads. The value of the counter is initialized on creation. Threads may
    block on the latch until the counter is decremented to zero. There is no
    possibility to increase or reset the counter, which makes the latch a
    single-use barrier.
    
    Example:
    
      const int N = 32;
      folly::Latch latch(N);
      std::vector<std::thread> threads;
      for (int i = 0; i < N; i++) {
        threads.emplace_back([&] {
          do_some_work();
          latch.count_down();
        });
      }
      latch.wait();
    
    A latch can be used to easily wait for mocked async methods in tests:
    
      ACTION_P(DecrementLatchImpl, latch) {
        latch.count_down();
      }
      constexpr auto DecrementLatch = DecrementLatchImpl<folly::Latch&>;
    
      class MockableObject {
       public:
        MOCK_METHOD(void, someAsyncEvent, ());
      };
    
      TEST(TestSuite, TestFeature) {
        MockableObject mockObjA;
        MockableObject mockObjB;
    
        folly::Latch latch(5);
    
        EXPECT_CALL(mockObjA, someAsyncEvent())
            .Times(2)
            .WillRepeatedly(DecrementLatch(latch)); // called 2 times
    
        EXPECT_CALL(mockObjB, someAsyncEvent())
            .Times(3)
            .WillRepeatedly(DecrementLatch(latch)); // called 3 times
    
        // trigger async events
        // ...
    
        EXPECT_TRUE(latch.try_wait_for(std::chrono::seconds(60)));
      }
    
    Reviewed By: yfeldblum
    
    Differential Revision: D28951720
    
    fbshipit-source-id: 6a9e20ad925a38d1cdb0134eedad826771bef3e0
    dc7ba0b5
Latch.h 5.11 KB