Skip to content

Commit

Permalink
cancel_after is supported.
Browse files Browse the repository at this point in the history
  • Loading branch information
klemens-morgenstern committed Jul 4, 2024
1 parent 143900c commit 41150f8
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 10 deletions.
19 changes: 13 additions & 6 deletions include/boost/cobalt/detail/spawn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,15 @@ namespace boost::cobalt::detail

struct async_initiate_spawn
{

async_initiate_spawn(executor exec) : exec(exec) {}

using executor_type = executor;
const executor_type & get_executor() const {return exec;}
executor exec;

template<typename Handler, typename T>
void operator()(Handler && h, task<T> a, executor exec)
void operator()(Handler && h, task<T> a)
{
auto & rec = a.receiver_;
if (rec.done)
Expand All @@ -44,9 +51,9 @@ struct async_initiate_spawn
auto sl = asio::get_associated_cancellation_slot(h);
if (sl.is_connected())
sl.assign(
[exec, recs](asio::cancellation_type ct)
[ex = exec, recs](asio::cancellation_type ct)
{
asio::dispatch(exec, [recs, ct] {recs->cancel(ct);});
asio::dispatch(ex, [recs, ct] {recs->cancel(ct);});
});

auto p = recs.get();
Expand Down Expand Up @@ -88,7 +95,7 @@ struct async_initiate_spawn
}

template<typename Handler>
void operator()(Handler && h, task<void> a, executor exec)
void operator()(Handler && h, task<void> a)
{
if (a.receiver_.done)
return asio::dispatch(
Expand All @@ -110,9 +117,9 @@ struct async_initiate_spawn
auto sl = asio::get_associated_cancellation_slot(h);
if (sl.is_connected())
sl.assign(
[exec, recs](asio::cancellation_type ct)
[ex = exec, recs](asio::cancellation_type ct)
{
asio::dispatch(exec, [recs, ct] {recs->cancel(ct);});
asio::dispatch(ex, [recs, ct] {recs->cancel(ct);});
});

auto p = recs.get();
Expand Down
8 changes: 4 additions & 4 deletions include/boost/cobalt/spawn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ auto spawn(Context & context,
CompletionToken&& token)
{
return asio::async_initiate<CompletionToken, void(std::exception_ptr, T)>(
detail::async_initiate_spawn{}, token, std::move(t), context.get_executor());
detail::async_initiate_spawn{context.get_executor()}, token, std::move(t));
}

template<std::convertible_to<executor> Executor, typename T, typename CompletionToken>
auto spawn(Executor executor, task<T> && t,
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor))
{
return asio::async_initiate<CompletionToken, void(std::exception_ptr, T)>(
detail::async_initiate_spawn{}, token, std::move(t), executor);
detail::async_initiate_spawn{executor}, token, std::move(t));
}

template<with_get_executor Context, typename CompletionToken>
Expand All @@ -36,15 +36,15 @@ auto spawn(Context & context,
CompletionToken&& token)
{
return asio::async_initiate<CompletionToken, void(std::exception_ptr)>(
detail::async_initiate_spawn{}, token, std::move(t), context.get_executor());
detail::async_initiate_spawn{context.get_executor()}, token, std::move(t));
}

template<std::convertible_to<executor> Executor, typename CompletionToken>
auto spawn(Executor executor, task<void> && t,
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor))
{
return asio::async_initiate<CompletionToken, void(std::exception_ptr)>(
detail::async_initiate_spawn{}, token, std::move(t), executor);
detail::async_initiate_spawn{executor}, token, std::move(t));

}

Expand Down
29 changes: 29 additions & 0 deletions test/task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <boost/test/unit_test.hpp>
#include "test.hpp"
#include <boost/asio/cancel_after.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/asio/awaitable.hpp>
Expand Down Expand Up @@ -327,5 +328,33 @@ BOOST_AUTO_TEST_CASE(cancel_task_)
#endif


CO_TEST_CASE(cancel_task_after)
{
try
{
auto exec = co_await cobalt::this_coro::executor;
co_await cobalt::spawn(
exec,
[]() -> cobalt::task<void>
{
asio::steady_timer t{co_await cobalt::this_coro::executor, std::chrono::steady_clock::time_point::max()};
co_await t.async_wait();
}(),
asio::cancel_after(std::chrono::milliseconds(1)));

BOOST_FAIL("Unreachable");
}
catch(system::system_error & se)
{
BOOST_CHECK(se.code() == asio::error::operation_aborted);
}
catch(...)
{
BOOST_FAIL("Unreachable");
}
}




BOOST_AUTO_TEST_SUITE_END();

0 comments on commit 41150f8

Please sign in to comment.