Skip to content

Commit 41150f8

Browse files
cancel_after is supported.
1 parent 143900c commit 41150f8

File tree

3 files changed

+46
-10
lines changed

3 files changed

+46
-10
lines changed

include/boost/cobalt/detail/spawn.hpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,15 @@ namespace boost::cobalt::detail
2424

2525
struct async_initiate_spawn
2626
{
27+
28+
async_initiate_spawn(executor exec) : exec(exec) {}
29+
30+
using executor_type = executor;
31+
const executor_type & get_executor() const {return exec;}
32+
executor exec;
33+
2734
template<typename Handler, typename T>
28-
void operator()(Handler && h, task<T> a, executor exec)
35+
void operator()(Handler && h, task<T> a)
2936
{
3037
auto & rec = a.receiver_;
3138
if (rec.done)
@@ -44,9 +51,9 @@ struct async_initiate_spawn
4451
auto sl = asio::get_associated_cancellation_slot(h);
4552
if (sl.is_connected())
4653
sl.assign(
47-
[exec, recs](asio::cancellation_type ct)
54+
[ex = exec, recs](asio::cancellation_type ct)
4855
{
49-
asio::dispatch(exec, [recs, ct] {recs->cancel(ct);});
56+
asio::dispatch(ex, [recs, ct] {recs->cancel(ct);});
5057
});
5158

5259
auto p = recs.get();
@@ -88,7 +95,7 @@ struct async_initiate_spawn
8895
}
8996

9097
template<typename Handler>
91-
void operator()(Handler && h, task<void> a, executor exec)
98+
void operator()(Handler && h, task<void> a)
9299
{
93100
if (a.receiver_.done)
94101
return asio::dispatch(
@@ -110,9 +117,9 @@ struct async_initiate_spawn
110117
auto sl = asio::get_associated_cancellation_slot(h);
111118
if (sl.is_connected())
112119
sl.assign(
113-
[exec, recs](asio::cancellation_type ct)
120+
[ex = exec, recs](asio::cancellation_type ct)
114121
{
115-
asio::dispatch(exec, [recs, ct] {recs->cancel(ct);});
122+
asio::dispatch(ex, [recs, ct] {recs->cancel(ct);});
116123
});
117124

118125
auto p = recs.get();

include/boost/cobalt/spawn.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ auto spawn(Context & context,
1919
CompletionToken&& token)
2020
{
2121
return asio::async_initiate<CompletionToken, void(std::exception_ptr, T)>(
22-
detail::async_initiate_spawn{}, token, std::move(t), context.get_executor());
22+
detail::async_initiate_spawn{context.get_executor()}, token, std::move(t));
2323
}
2424

2525
template<std::convertible_to<executor> Executor, typename T, typename CompletionToken>
2626
auto spawn(Executor executor, task<T> && t,
2727
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor))
2828
{
2929
return asio::async_initiate<CompletionToken, void(std::exception_ptr, T)>(
30-
detail::async_initiate_spawn{}, token, std::move(t), executor);
30+
detail::async_initiate_spawn{executor}, token, std::move(t));
3131
}
3232

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

4242
template<std::convertible_to<executor> Executor, typename CompletionToken>
4343
auto spawn(Executor executor, task<void> && t,
4444
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor))
4545
{
4646
return asio::async_initiate<CompletionToken, void(std::exception_ptr)>(
47-
detail::async_initiate_spawn{}, token, std::move(t), executor);
47+
detail::async_initiate_spawn{executor}, token, std::move(t));
4848

4949
}
5050

test/task.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include <boost/test/unit_test.hpp>
1515
#include "test.hpp"
16+
#include <boost/asio/cancel_after.hpp>
1617
#include <boost/asio/detached.hpp>
1718
#include <boost/asio/steady_timer.hpp>
1819
#include <boost/asio/awaitable.hpp>
@@ -327,5 +328,33 @@ BOOST_AUTO_TEST_CASE(cancel_task_)
327328
#endif
328329

329330

331+
CO_TEST_CASE(cancel_task_after)
332+
{
333+
try
334+
{
335+
auto exec = co_await cobalt::this_coro::executor;
336+
co_await cobalt::spawn(
337+
exec,
338+
[]() -> cobalt::task<void>
339+
{
340+
asio::steady_timer t{co_await cobalt::this_coro::executor, std::chrono::steady_clock::time_point::max()};
341+
co_await t.async_wait();
342+
}(),
343+
asio::cancel_after(std::chrono::milliseconds(1)));
344+
345+
BOOST_FAIL("Unreachable");
346+
}
347+
catch(system::system_error & se)
348+
{
349+
BOOST_CHECK(se.code() == asio::error::operation_aborted);
350+
}
351+
catch(...)
352+
{
353+
BOOST_FAIL("Unreachable");
354+
}
355+
}
356+
357+
358+
330359

331360
BOOST_AUTO_TEST_SUITE_END();

0 commit comments

Comments
 (0)