From 875b720f9051167653e9441ae78ad9a1987eaaa5 Mon Sep 17 00:00:00 2001 From: Attila Date: Thu, 8 Mar 2018 13:53:59 +0100 Subject: [PATCH 1/3] Fix typo in async_generator state description --- include/cppcoro/async_generator.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/cppcoro/async_generator.hpp b/include/cppcoro/async_generator.hpp index 49cd05ce..f188d195 100644 --- a/include/cppcoro/async_generator.hpp +++ b/include/cppcoro/async_generator.hpp @@ -117,8 +117,8 @@ namespace cppcoro // State transition diagram // VNRCA - value_not_ready_consumer_active // VNRCS - value_not_ready_consumer_suspended - // VRPA - value_ready_consumer_active - // VRPS - value_ready_consumer_suspended + // VRPA - value_ready_producer_active + // VRPS - value_ready_producer_suspended // // A +--- VNRCA --[C]--> VNRCS yield_value() // | | | A | A | . From e899e65fb0d146767531c7b34f03b39d54cc7186 Mon Sep 17 00:00:00 2001 From: Attila Date: Thu, 8 Mar 2018 13:54:14 +0100 Subject: [PATCH 2/3] Implement io_service::process_events_until_complete Closes https://github.com/lewissbaker/cppcoro/issues/30 --- README.md | 3 +++ include/cppcoro/io_service.hpp | 27 +++++++++++++++++++++++++++ test/io_service_tests.cpp | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/README.md b/README.md index b4fa93b1..ff77cb48 100644 --- a/README.md +++ b/README.md @@ -1144,6 +1144,9 @@ namespace cppcoro std::uint64_t process_one_event(); std::uint64_t process_one_pending_event(); + template + decltype(auto) process_events_until_complete(TASK&& task); + // Request that all threads processing events exit their event loops. void stop() noexcept; diff --git a/include/cppcoro/io_service.hpp b/include/cppcoro/io_service.hpp index 27867c58..464cf09e 100644 --- a/include/cppcoro/io_service.hpp +++ b/include/cppcoro/io_service.hpp @@ -79,6 +79,13 @@ namespace cppcoro const std::chrono::duration& delay, cancellation_token cancellationToken = {}) noexcept; + /// Process events until the task completes. + /// + /// \return + /// Result of the co_await task. + template + decltype(auto) process_events_until_complete(TASK&& task); + /// Process events until the io_service is stopped. /// /// \return @@ -178,6 +185,26 @@ namespace cppcoro }; + template + decltype(auto) io_service::process_events_until_complete(TASK&& task) + { + if (!task.is_ready()) + { + auto callback = [](void* io) noexcept + { + static_cast(io)->stop(); + }; + + auto starter = task.get_starter(); + starter.start(cppcoro::detail::continuation{ callback, this }); + + process_events(); + reset(); + } + + return std::forward(task).operator co_await().await_resume(); + } + class io_service::schedule_operation { public: diff --git a/test/io_service_tests.cpp b/test/io_service_tests.cpp index ddf5db31..a4cf2e43 100644 --- a/test/io_service_tests.cpp +++ b/test/io_service_tests.cpp @@ -226,4 +226,36 @@ TEST_CASE_FIXTURE(io_service_fixture_with_threads<1>, "Many concurrent timers") << "ms"); } +TEST_CASE("io_service::process_events_until_complete(task)") +{ + cppcoro::io_service ioService; + + auto makeTask = [](cppcoro::io_service& io) -> cppcoro::task + { + co_await io.schedule(); + co_return "foo"; + }; + + auto task = makeTask(ioService); + + CHECK(ioService.process_events_until_complete(task) == "foo"); + CHECK(ioService.process_events_until_complete(makeTask(ioService)) == "foo"); +} + +TEST_CASE("io_service::process_events_until_complete(shared_task)") +{ + cppcoro::io_service ioService; + + auto makeTask = [](cppcoro::io_service& io) -> cppcoro::shared_task + { + co_await io.schedule(); + co_return "foo"; + }; + + auto task = makeTask(ioService); + + CHECK(ioService.process_events_until_complete(task) == "foo"); + CHECK(ioService.process_events_until_complete(makeTask(ioService)) == "foo"); +} + TEST_SUITE_END(); From 0f405ba7540899fc2a384c184addce838a1012e1 Mon Sep 17 00:00:00 2001 From: Attila Date: Thu, 15 Mar 2018 11:46:41 +0100 Subject: [PATCH 3/3] Fixup: Test io_service::process_events_until_complete with completed task --- test/io_service_tests.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/io_service_tests.cpp b/test/io_service_tests.cpp index a4cf2e43..a343b7cc 100644 --- a/test/io_service_tests.cpp +++ b/test/io_service_tests.cpp @@ -238,6 +238,8 @@ TEST_CASE("io_service::process_events_until_complete(task)") auto task = makeTask(ioService); + CHECK(ioService.process_events_until_complete(task) == "foo"); + CHECK(task.is_ready()); CHECK(ioService.process_events_until_complete(task) == "foo"); CHECK(ioService.process_events_until_complete(makeTask(ioService)) == "foo"); } @@ -254,6 +256,8 @@ TEST_CASE("io_service::process_events_until_complete(shared_task)") auto task = makeTask(ioService); + CHECK(ioService.process_events_until_complete(task) == "foo"); + CHECK(task.is_ready()); CHECK(ioService.process_events_until_complete(task) == "foo"); CHECK(ioService.process_events_until_complete(makeTask(ioService)) == "foo"); }