@@ -38,14 +38,14 @@ static Task<void> async_throw() {
38
38
throw TestException ();
39
39
}
40
40
41
- static Task<void > wait_until_cancelled (bool * is_cancelled) {
41
+ static Task<void > wait_until_cancelled (bool & is_cancelled) {
42
42
try {
43
43
auto executor = co_await this_coro::executor;
44
44
steady_timer timer (executor);
45
45
timer.expires_after (1h);
46
46
co_await timer.async_wait (use_awaitable);
47
47
} catch (const boost::system::system_error&) {
48
- * is_cancelled = true ;
48
+ is_cancelled = true ;
49
49
}
50
50
}
51
51
@@ -76,7 +76,7 @@ TEST_CASE("TaskGroup.1.wait_until_cancelled") {
76
76
auto executor = runner.executor ();
77
77
TaskGroup group{executor, 1 };
78
78
bool is_cancelled = false ;
79
- group.spawn (executor, wait_until_cancelled (& is_cancelled));
79
+ group.spawn (executor, wait_until_cancelled (is_cancelled));
80
80
CHECK_THROWS_AS (runner.run (group.wait () && async_throw ()), TestException);
81
81
CHECK (is_cancelled);
82
82
}
@@ -86,9 +86,9 @@ TEST_CASE("TaskGroup.some.wait_until_cancelled") {
86
86
auto executor = runner.executor ();
87
87
TaskGroup group{executor, 3 };
88
88
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 ]));
92
92
CHECK_THROWS_AS (runner.run (group.wait () && async_throw ()), TestException);
93
93
CHECK (is_cancelled[0 ]);
94
94
CHECK (is_cancelled[1 ]);
@@ -101,11 +101,11 @@ TEST_CASE("TaskGroup.some.mix") {
101
101
TaskGroup group{executor, 6 };
102
102
std::array<bool , 3 > is_cancelled{};
103
103
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 ]));
105
105
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 ]));
107
107
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 ]));
109
109
CHECK_THROWS_AS (runner.run (group.wait () && async_throw ()), TestException);
110
110
CHECK (is_cancelled[0 ]);
111
111
CHECK (is_cancelled[1 ]);
@@ -156,11 +156,11 @@ TEST_CASE("TaskGroup.task_cancelled_exception_is_ignored") {
156
156
TEST_CASE (" TaskGroup.task_exception_during_cancellation_is_rethrown" ) {
157
157
test_util::TaskRunner runner;
158
158
auto executor = runner.executor ();
159
- TaskGroup group{executor, 1 };
159
+ TaskGroup group{executor, 2 };
160
160
161
161
auto task = [&]() -> Task<void > {
162
162
bool is_cancelled = false ;
163
- co_await wait_until_cancelled (& is_cancelled);
163
+ co_await wait_until_cancelled (is_cancelled);
164
164
if (is_cancelled) {
165
165
throw std::runtime_error (" exception_during_cancellation" );
166
166
}
@@ -181,4 +181,31 @@ TEST_CASE("TaskGroup.task_exception_during_cancellation_is_rethrown") {
181
181
CHECK (runner.run (test ()));
182
182
}
183
183
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
+
184
211
} // namespace silkworm::concurrency
0 commit comments