@@ -38,14 +38,14 @@ static Task<void> async_throw() {
3838 throw TestException ();
3939}
4040
41- static Task<void > wait_until_cancelled (bool * is_cancelled) {
41+ static Task<void > wait_until_cancelled (bool & is_cancelled) {
4242 try {
4343 auto executor = co_await this_coro::executor;
4444 steady_timer timer (executor);
4545 timer.expires_after (1h);
4646 co_await timer.async_wait (use_awaitable);
4747 } catch (const boost::system::system_error&) {
48- * is_cancelled = true ;
48+ is_cancelled = true ;
4949 }
5050}
5151
@@ -76,7 +76,7 @@ TEST_CASE("TaskGroup.1.wait_until_cancelled") {
7676 auto executor = runner.executor ();
7777 TaskGroup group{executor, 1 };
7878 bool is_cancelled = false ;
79- group.spawn (executor, wait_until_cancelled (& is_cancelled));
79+ group.spawn (executor, wait_until_cancelled (is_cancelled));
8080 CHECK_THROWS_AS (runner.run (group.wait () && async_throw ()), TestException);
8181 CHECK (is_cancelled);
8282}
@@ -86,9 +86,9 @@ TEST_CASE("TaskGroup.some.wait_until_cancelled") {
8686 auto executor = runner.executor ();
8787 TaskGroup group{executor, 3 };
8888 std::array<bool , 3 > is_cancelled{};
89- group.spawn (executor, wait_until_cancelled (& is_cancelled[0 ]));
90- group.spawn (executor, wait_until_cancelled (& is_cancelled[1 ]));
91- group.spawn (executor, wait_until_cancelled (& is_cancelled[2 ]));
89+ group.spawn (executor, wait_until_cancelled (is_cancelled[0 ]));
90+ group.spawn (executor, wait_until_cancelled (is_cancelled[1 ]));
91+ group.spawn (executor, wait_until_cancelled (is_cancelled[2 ]));
9292 CHECK_THROWS_AS (runner.run (group.wait () && async_throw ()), TestException);
9393 CHECK (is_cancelled[0 ]);
9494 CHECK (is_cancelled[1 ]);
@@ -101,11 +101,11 @@ TEST_CASE("TaskGroup.some.mix") {
101101 TaskGroup group{executor, 6 };
102102 std::array<bool , 3 > is_cancelled{};
103103 group.spawn (executor, async_ok ());
104- group.spawn (executor, wait_until_cancelled (& is_cancelled[0 ]));
104+ group.spawn (executor, wait_until_cancelled (is_cancelled[0 ]));
105105 group.spawn (executor, async_ok ());
106- group.spawn (executor, wait_until_cancelled (& is_cancelled[1 ]));
106+ group.spawn (executor, wait_until_cancelled (is_cancelled[1 ]));
107107 group.spawn (executor, async_ok ());
108- group.spawn (executor, wait_until_cancelled (& is_cancelled[2 ]));
108+ group.spawn (executor, wait_until_cancelled (is_cancelled[2 ]));
109109 CHECK_THROWS_AS (runner.run (group.wait () && async_throw ()), TestException);
110110 CHECK (is_cancelled[0 ]);
111111 CHECK (is_cancelled[1 ]);
@@ -156,11 +156,11 @@ TEST_CASE("TaskGroup.task_cancelled_exception_is_ignored") {
156156TEST_CASE (" TaskGroup.task_exception_during_cancellation_is_rethrown" ) {
157157 test_util::TaskRunner runner;
158158 auto executor = runner.executor ();
159- TaskGroup group{executor, 1 };
159+ TaskGroup group{executor, 2 };
160160
161161 auto task = [&]() -> Task<void > {
162162 bool is_cancelled = false ;
163- co_await wait_until_cancelled (& is_cancelled);
163+ co_await wait_until_cancelled (is_cancelled);
164164 if (is_cancelled) {
165165 throw std::runtime_error (" exception_during_cancellation" );
166166 }
@@ -181,4 +181,31 @@ TEST_CASE("TaskGroup.task_exception_during_cancellation_is_rethrown") {
181181 CHECK (runner.run (test ()));
182182}
183183
184+ TEST_CASE (" TaskGroup.avoid_max_tasks_limit_breach" ) {
185+ log::init (log::Settings{
186+ .log_std_out = true ,
187+ .log_nocolor = true ,
188+ .log_threads = true ,
189+ .log_verbosity = log::Level::kInfo ,
190+ });
191+ test_util::TaskRunner runner;
192+ auto executor = runner.executor ();
193+ const size_t max_tasks = 10 ;
194+ TaskGroup group{executor, max_tasks};
195+
196+ auto task = [&]() -> Task<void > {
197+ bool is_cancelled = false ;
198+ co_await wait_until_cancelled (is_cancelled);
199+ if (is_cancelled) {
200+ throw std::runtime_error (" exception_during_cancellation" );
201+ }
202+ };
203+ // Spawn max_tasks tasks
204+ for (size_t i = 0 ; i < max_tasks; ++i) {
205+ REQUIRE_NOTHROW (group.spawn (executor, task ()));
206+ }
207+ // Trying to spawn one more *must* trigger MaxTasksReachedError exception
208+ CHECK_THROWS_AS (group.spawn (executor, task ()), TaskGroup::MaxTasksReachedError);
209+ }
210+
184211} // namespace silkworm::concurrency
0 commit comments