14 #ifdef LIBCOTASK_MACRO_ENABLED
16 # if defined(LIBCOPP_MACRO_ENABLE_STD_COROUTINE) && LIBCOPP_MACRO_ENABLE_STD_COROUTINE
19 struct task_manager_future_private_data {};
21 using task_future_int_type = cotask::task_future<int, task_manager_future_private_data>;
22 using generator_future_int_type = copp::generator_future<int>;
24 std::list<generator_future_int_type::context_pointer_type> g_task_manager_future_pending_int_contexts;
25 size_t g_task_manager_future_resume_generator_count = 0;
26 size_t g_task_manager_future_suspend_generator_count = 0;
28 static size_t task_manager_resume_pending_contexts(std::list<int> values,
int max_count = 32767) {
30 while (max_count > 0 && !g_task_manager_future_pending_int_contexts.empty()) {
32 if (!g_task_manager_future_pending_int_contexts.empty()) {
33 auto ctx = *g_task_manager_future_pending_int_contexts.begin();
34 g_task_manager_future_pending_int_contexts.pop_front();
36 if (!values.empty()) {
37 int val = values.front();
51 static void task_manager_generator_int_suspend_callback(generator_future_int_type::context_pointer_type ctx) {
52 ++g_task_manager_future_suspend_generator_count;
53 g_task_manager_future_pending_int_contexts.push_back(ctx);
55 static void task_manager_generator_int_resume_callback(
const generator_future_int_type::context_type&) {
56 ++g_task_manager_future_resume_generator_count;
59 static task_future_int_type task_func_await_int() {
60 generator_future_int_type generator{task_manager_generator_int_suspend_callback,
61 task_manager_generator_int_resume_callback};
62 auto gen_res = co_await generator;
68 CASE_TEST(task_promise_task_manager, tickspec_t) {
69 cotask::detail::tickspec_t l;
70 cotask::detail::tickspec_t r;
100 CASE_TEST(task_promise_task_manager, task_timer_node) {
101 cotask::detail::task_timer_node<task_future_int_type::id_type> l;
102 cotask::detail::task_timer_node<task_future_int_type::id_type> r;
104 l.expired_time.tv_sec = 123;
105 l.expired_time.tv_nsec = 456;
108 r.expired_time.tv_sec = 123;
109 r.expired_time.tv_nsec = 456;
124 r.expired_time.tv_nsec = 45;
132 r.expired_time.tv_nsec = 456;
140 r.expired_time.tv_nsec = 4567;
149 CASE_TEST(task_promise_task_manager, add_and_timeout) {
151 task_future_int_type co_task = task_func_await_int();
152 task_future_int_type co_another_task = task_func_await_int();
154 using mgr_t = cotask::task_manager<task_future_int_type>;
155 mgr_t::ptr_type
task_mgr = mgr_t::create();
158 size_t old_resume_generator_count = g_task_manager_future_resume_generator_count;
159 size_t old_suspend_generator_count = g_task_manager_future_suspend_generator_count;
162 task_mgr->add_task(co_another_task);
181 CASE_EXPECT_EQ(8, (
int)
task_mgr->get_container().find(co_task.get_id())->second.timer_node->expired_time.tv_sec);
185 CASE_EXPECT_FALSE(task_future_int_type::task_status_type::kTimeout == co_task.get_status());
192 CASE_EXPECT_TRUE(task_future_int_type::task_status_type::kTimeout == co_task.get_status());
197 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_manager_future_resume_generator_count);
198 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_manager_future_suspend_generator_count);
202 CASE_EXPECT_TRUE(task_future_int_type::task_status_type::kRunning == co_another_task.get_status());
204 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_manager_future_resume_generator_count);
205 CASE_EXPECT_EQ(old_suspend_generator_count + 2, g_task_manager_future_suspend_generator_count);
207 task_manager_resume_pending_contexts({901, 902});
209 CASE_EXPECT_EQ(old_resume_generator_count + 2, g_task_manager_future_resume_generator_count);
210 CASE_EXPECT_EQ(old_suspend_generator_count + 2, g_task_manager_future_suspend_generator_count);
212 CASE_EXPECT_TRUE(task_future_int_type::task_status_type::kTimeout == co_task.get_status());
213 CASE_EXPECT_TRUE(task_future_int_type::task_status_type::kDone == co_another_task.get_status());
222 task_manager_resume_pending_contexts({});
225 CASE_TEST(task_promise_task_manager, add_and_timeout_no_start) {
227 task_future_int_type co_task = task_func_await_int();
228 task_future_int_type co_another_task = task_func_await_int();
230 using mgr_t = cotask::task_manager<task_future_int_type>;
231 mgr_t::ptr_type
task_mgr = mgr_t::create();
234 size_t old_resume_generator_count = g_task_manager_future_resume_generator_count;
235 size_t old_suspend_generator_count = g_task_manager_future_suspend_generator_count;
238 task_mgr->add_task(co_another_task);
252 CASE_EXPECT_EQ(8, (
int)
task_mgr->get_container().find(co_task.get_id())->second.timer_node->expired_time.tv_sec);
256 CASE_EXPECT_FALSE(task_future_int_type::task_status_type::kTimeout == co_task.get_status());
263 CASE_EXPECT_TRUE(task_future_int_type::task_status_type::kTimeout == co_task.get_status());
268 CASE_EXPECT_EQ(old_resume_generator_count, g_task_manager_future_resume_generator_count);
269 CASE_EXPECT_EQ(old_suspend_generator_count, g_task_manager_future_suspend_generator_count);
273 CASE_EXPECT_TRUE(task_future_int_type::task_status_type::kRunning == co_another_task.get_status());
275 CASE_EXPECT_EQ(old_resume_generator_count, g_task_manager_future_resume_generator_count);
276 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_manager_future_suspend_generator_count);
278 task_manager_resume_pending_contexts({901, 902});
280 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_manager_future_resume_generator_count);
281 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_manager_future_suspend_generator_count);
283 CASE_EXPECT_TRUE(task_future_int_type::task_status_type::kTimeout == co_task.get_status());
284 CASE_EXPECT_TRUE(task_future_int_type::task_status_type::kDone == co_another_task.get_status());
293 task_manager_resume_pending_contexts({});
296 CASE_TEST(task_promise_task_manager, add_and_timeout_last_reference) {
298 size_t old_resume_generator_count = g_task_manager_future_resume_generator_count;
299 size_t old_suspend_generator_count = g_task_manager_future_suspend_generator_count;
300 using mgr_t = cotask::task_manager<task_future_int_type>;
301 mgr_t::ptr_type
task_mgr = mgr_t::create();
303 task_future_int_type::id_type another_task_id;
304 task_future_int_type::id_type task_id;
306 task_future_int_type co_task = task_func_await_int();
307 task_future_int_type co_another_task = task_func_await_int();
312 another_task_id = co_another_task.get_id();
313 task_id = co_task.get_id();
315 task_mgr->add_task(std::move(co_task), 5, 0);
316 task_mgr->add_task(std::move(co_another_task));
341 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_manager_future_resume_generator_count);
342 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_manager_future_suspend_generator_count);
346 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_manager_future_resume_generator_count);
347 CASE_EXPECT_EQ(old_suspend_generator_count + 2, g_task_manager_future_suspend_generator_count);
349 task_manager_resume_pending_contexts({901, 902});
351 CASE_EXPECT_EQ(old_resume_generator_count + 2, g_task_manager_future_resume_generator_count);
352 CASE_EXPECT_EQ(old_suspend_generator_count + 2, g_task_manager_future_suspend_generator_count);
357 task_manager_resume_pending_contexts({});
360 CASE_TEST(task_promise_task_manager, kill) {
362 size_t old_resume_generator_count = g_task_manager_future_resume_generator_count;
363 size_t old_suspend_generator_count = g_task_manager_future_suspend_generator_count;
364 using mgr_t = cotask::task_manager<task_future_int_type>;
365 mgr_t::ptr_type
task_mgr = mgr_t::create();
367 task_future_int_type co_task = task_func_await_int();
368 task_future_int_type co_another_task = task_func_await_int();
374 task_mgr->add_task(co_another_task, 10, 0);
377 task_mgr->start(co_another_task.get_id());
383 task_mgr->cancel(co_another_task.get_id());
385 CASE_EXPECT_EQ(old_resume_generator_count + 2, g_task_manager_future_resume_generator_count);
386 CASE_EXPECT_EQ(old_suspend_generator_count + 2, g_task_manager_future_suspend_generator_count);
391 CASE_EXPECT_TRUE(task_future_int_type::task_status_type::kKilled == co_task.get_status());
392 CASE_EXPECT_TRUE(task_future_int_type::task_status_type::kCancle == co_another_task.get_status());
395 task_manager_resume_pending_contexts({});
398 CASE_TEST(task_promise_task_manager, duplicated_checkpoints) {
400 size_t old_resume_generator_count = g_task_manager_future_resume_generator_count;
401 size_t old_suspend_generator_count = g_task_manager_future_suspend_generator_count;
402 using mgr_t = cotask::task_manager<task_future_int_type>;
403 mgr_t::ptr_type
task_mgr = mgr_t::create();
405 task_future_int_type co_task = task_func_await_int();
426 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_manager_future_resume_generator_count);
427 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_manager_future_suspend_generator_count);
429 task_manager_resume_pending_contexts({});
432 CASE_TEST(task_promise_task_manager, update_timeout) {
434 size_t old_resume_generator_count = g_task_manager_future_resume_generator_count;
435 size_t old_suspend_generator_count = g_task_manager_future_suspend_generator_count;
436 using mgr_t = cotask::task_manager<task_future_int_type>;
437 mgr_t::ptr_type
task_mgr = mgr_t::create();
439 task_future_int_type co_task = task_func_await_int();
464 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_manager_future_resume_generator_count);
465 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_manager_future_suspend_generator_count);
467 task_manager_resume_pending_contexts({});
472 # if defined(LIBCOTASK_MACRO_AUTO_CLEANUP_MANAGER) && LIBCOTASK_MACRO_AUTO_CLEANUP_MANAGER
473 CASE_TEST(task_promise_task_manager, auto_cleanup_for_manager) {
475 size_t old_resume_generator_count = g_task_manager_future_resume_generator_count;
476 size_t old_suspend_generator_count = g_task_manager_future_suspend_generator_count;
477 using mgr_t = cotask::task_manager<task_future_int_type>;
479 task_future_int_type co_task = task_func_await_int();
481 mgr_t::ptr_type task_mgr1 = mgr_t::create();
482 mgr_t::ptr_type task_mgr2 = mgr_t::create();
491 task_manager_resume_pending_contexts({903});
496 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_manager_future_resume_generator_count);
497 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_manager_future_suspend_generator_count);
499 task_manager_resume_pending_contexts({});
502 CASE_TEST(task_promise_task_manager, remove_last_task_in_manager) {
504 size_t old_resume_generator_count = g_task_manager_future_resume_generator_count;
505 size_t old_suspend_generator_count = g_task_manager_future_suspend_generator_count;
506 using mgr_t = cotask::task_manager<task_future_int_type>;
508 mgr_t::ptr_type task_mgr1 = mgr_t::create();
511 task_future_int_type co_task = task_func_await_int();
524 task_manager_resume_pending_contexts({903});
529 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_manager_future_resume_generator_count);
530 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_manager_future_suspend_generator_count);
532 task_manager_resume_pending_contexts({});
538 # if 0 && defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
540 static task_future_int_type task_func_await_int_start_exception() {
541 generator_future_int_type generator{task_manager_generator_int_suspend_callback,
542 task_manager_generator_int_resume_callback};
544 throw std::exception(
"test-exception-start");
546 auto gen_res = co_await generator;
550 static task_future_int_type task_func_await_int_resume_exception() {
551 generator_future_int_type generator{task_manager_generator_int_suspend_callback,
552 task_manager_generator_int_resume_callback};
554 auto gen_res = co_await generator;
556 throw std::exception(
"test-exception-resume");
563 CASE_TEST(task_promise_task_manager, start_exception_safe) {
565 size_t old_resume_generator_count = g_task_manager_future_resume_generator_count;
566 size_t old_suspend_generator_count = g_task_manager_future_suspend_generator_count;
567 using mgr_t = cotask::task_manager<task_future_int_type>;
569 task_future_int_type co_task = task_func_await_int_start_exception();
570 mgr_t::ptr_type
task_mgr = mgr_t::create();
579 task_manager_resume_pending_contexts({907});
580 }
catch (
const std::exception& e) {
581 CASE_MSG_INFO() <<
"Catch a exception: " << e.what() << std::endl;
590 CASE_EXPECT_EQ(old_resume_generator_count, g_task_manager_future_resume_generator_count);
591 CASE_EXPECT_EQ(old_suspend_generator_count, g_task_manager_future_suspend_generator_count);
593 task_manager_resume_pending_contexts({});
596 CASE_TEST(task_promise_task_manager, resume_exception_safe) {
598 size_t old_resume_generator_count = g_task_manager_future_resume_generator_count;
599 size_t old_suspend_generator_count = g_task_manager_future_suspend_generator_count;
600 using mgr_t = cotask::task_manager<task_future_int_type>;
602 task_future_int_type co_task = task_func_await_int_resume_exception();
603 mgr_t::ptr_type
task_mgr = mgr_t::create();
612 task_manager_resume_pending_contexts({907});
613 }
catch (
const std::exception& e) {
614 CASE_MSG_INFO() <<
"Catch a exception: " << e.what() << std::endl;
623 CASE_EXPECT_EQ(old_resume_generator_count, g_task_manager_future_resume_generator_count);
624 CASE_EXPECT_EQ(old_suspend_generator_count, g_task_manager_future_suspend_generator_count);
626 task_manager_resume_pending_contexts({});
632 CASE_TEST(task_promise_task_manager, disabled) {}
@ COPP_EC_SUCCESS
COPP_EC_SUCCESS.
@ COPP_EC_TASK_IS_EXITING
COPP_EC_TASK_IS_EXITING.
@ COPP_EC_TASK_ALREADY_IN_ANOTHER_MANAGER
COPP_EC_TASK_ALREADY_IN_ANOTHER_MANAGER.
cotask::task_manager< my_task_t > mgr_t
CASE_TEST(task_promise_task_manager, disabled)
#define CASE_EXPECT_FALSE(c)
#define CASE_EXPECT_EQ(l, r)
#define CASE_EXPECT_TRUE(c)