From 6a802b2359deb9e94a4b404928faace49263dc59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20W=C3=B3jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Tue, 2 Jul 2024 09:48:12 +0200 Subject: [PATCH] Do not wait for cancellation signal (#4664) * Do not wait for cancelation signal * Test * Explicit constructor --- nano/core_test/async.cpp | 22 +++++++++++++++++++++- nano/lib/async.hpp | 18 ++++++++---------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/nano/core_test/async.cpp b/nano/core_test/async.cpp index e0be0a732..cef6e082f 100644 --- a/nano/core_test/async.cpp +++ b/nano/core_test/async.cpp @@ -56,10 +56,30 @@ TEST (async, cancellation) cancellation.emit (); - ASSERT_EQ (fut.wait_for (500ms), std::future_status::ready); + ASSERT_EQ (fut.wait_for (1s), std::future_status::ready); ASSERT_NO_THROW (fut.get ()); } +// Test that cancellation signal behaves well when the cancellation is emitted after the task has completed +TEST (async, cancellation_lifetime) +{ + test_context ctx; + + nano::async::cancellation cancellation{ ctx.strand }; + { + auto fut = asio::co_spawn ( + ctx.strand, + [&] () -> asio::awaitable { + co_await nano::async::sleep_for (100ms); + }, + asio::bind_cancellation_slot (cancellation.slot (), asio::use_future)); + ASSERT_EQ (fut.wait_for (1s), std::future_status::ready); + fut.get (); + } + auto cancel_fut = cancellation.emit (); + ASSERT_EQ (cancel_fut.wait_for (1s), std::future_status::ready); +} + TEST (async, task) { nano::test::system system; diff --git a/nano/lib/async.hpp b/nano/lib/async.hpp index b217ba881..818d6bcaf 100644 --- a/nano/lib/async.hpp +++ b/nano/lib/async.hpp @@ -30,7 +30,7 @@ class cancellation public: explicit cancellation (nano::async::strand & strand) : strand{ strand }, - signal{ std::make_unique () } + signal{ std::make_shared () } { } @@ -49,12 +49,11 @@ public: }; public: - void emit (asio::cancellation_type type = asio::cancellation_type::all) + auto emit (asio::cancellation_type type = asio::cancellation_type::all) { - asio::dispatch (strand, asio::use_future ([this, type] () { - signal->emit (type); - })) - .wait (); + return asio::dispatch (strand, asio::use_future ([signal_l = signal, type] () { + signal_l->emit (type); + })); } auto slot () @@ -67,9 +66,8 @@ public: nano::async::strand & strand; private: - std::unique_ptr signal; // Wrap the signal in a unique_ptr to enable moving - - bool slotted{ false }; + std::shared_ptr signal; + bool slotted{ false }; // For debugging purposes }; /** @@ -82,7 +80,7 @@ public: // Only thread-like void tasks are supported for now using value_type = void; - task (nano::async::strand & strand) : + explicit task (nano::async::strand & strand) : strand{ strand }, cancellation{ strand } {