/////////////////////////////////////////////////////////////////////////////// // Copyright (c) Lewis Baker // Licenced under MIT license. See LICENSE.txt for details. /////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include "doctest/cppcoro_doctest.h" TEST_SUITE_BEGIN("async_latch"); using namespace cppcoro; TEST_CASE("latch constructed with zero count is initially ready") { async_latch latch(0); CHECK(latch.is_ready()); } TEST_CASE("latch constructed with negative count is initially ready") { async_latch latch(-3); CHECK(latch.is_ready()); } TEST_CASE("count_down and is_ready") { async_latch latch(3); CHECK(!latch.is_ready()); latch.count_down(); CHECK(!latch.is_ready()); latch.count_down(); CHECK(!latch.is_ready()); latch.count_down(); CHECK(latch.is_ready()); } TEST_CASE("count_down by n") { async_latch latch(5); latch.count_down(3); CHECK(!latch.is_ready()); latch.count_down(2); CHECK(latch.is_ready()); } TEST_CASE("single awaiter") { async_latch latch(2); bool after = false; sync_wait(when_all_ready( [&]() -> task<> { co_await latch; after = true; }(), [&]() -> task<> { CHECK(!after); latch.count_down(); CHECK(!after); latch.count_down(); CHECK(after); co_return; }() )); } TEST_CASE("multiple awaiters") { async_latch latch(2); bool after1 = false; bool after2 = false; bool after3 = false; sync_wait(when_all_ready( [&]() -> task<> { co_await latch; after1 = true; }(), [&]() -> task<> { co_await latch; after2 = true; }(), [&]() -> task<> { co_await latch; after3 = true; }(), [&]() -> task<> { CHECK(!after1); CHECK(!after2); CHECK(!after3); latch.count_down(); CHECK(!after1); CHECK(!after2); CHECK(!after3); latch.count_down(); CHECK(after1); CHECK(after2); CHECK(after3); co_return; }())); } TEST_SUITE_END();