libcopp  1.2.0
coroutine_task_test.cpp
Go to the documentation of this file.
1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 
6 
8 #include <libcotask/task.h>
9 
10 #include "frame/test_macros.h"
11 
12 #ifdef LIBCOTASK_MACRO_ENABLED
13 static int g_test_coroutine_task_status = 0;
14 static int g_test_coroutine_task_on_finished = 0;
15 class test_context_task_action_base : public cotask::impl::task_action_impl {
16 public:
17  // add a same name function to find the type detection error
18  virtual int operator()() = 0;
19 
20  int operator()(void *priv_data) {
21  ++g_test_coroutine_task_status;
22 
23  CASE_EXPECT_EQ(&g_test_coroutine_task_status, priv_data);
24 
26  cotask::this_task::get_task()->yield(&priv_data);
28 
30 
31  ++g_test_coroutine_task_status;
32 
33  return 0;
34  }
35 
36  virtual int on_finished(cotask::impl::task_impl &) {
37  ++g_test_coroutine_task_on_finished;
38  return 0;
39  }
40 };
41 
42 class test_context_task_action : public test_context_task_action_base {
43 public:
44  using test_context_task_action_base::operator();
45 
46  // add a same name function to find the type detection error
47  virtual int operator()() { return 0; }
48 };
49 
50 
51 CASE_TEST(coroutine_task, custom_action) {
53  g_test_coroutine_task_status = 0;
54  g_test_coroutine_task_on_finished = 0;
55 
56  {
57  task_ptr_type co_task = cotask::task<>::create(test_context_task_action());
58  task_ptr_type co_another_task = cotask::task<>::create(test_context_task_action()); // share action
59 
60  CASE_EXPECT_EQ(cotask::EN_TS_CREATED, co_task->get_status());
61  CASE_EXPECT_EQ(cotask::EN_TS_CREATED, co_another_task->get_status());
62 
63  CASE_EXPECT_EQ(0, co_task->start(&g_test_coroutine_task_status));
64 
65  CASE_EXPECT_EQ(g_test_coroutine_task_status, 1);
66  CASE_EXPECT_FALSE(co_task->is_completed());
67  CASE_EXPECT_FALSE(co_task->is_canceled());
68  CASE_EXPECT_FALSE(co_task->is_faulted());
69 
70  CASE_EXPECT_EQ(0, co_another_task->start(&g_test_coroutine_task_status));
71  CASE_EXPECT_EQ(g_test_coroutine_task_status, 2);
72 
73  CASE_EXPECT_EQ(cotask::EN_TS_WAITING, co_task->get_status());
74  CASE_EXPECT_EQ(cotask::EN_TS_WAITING, co_another_task->get_status());
75 
76  CASE_EXPECT_EQ(0, co_task->resume(co_task.get()));
77  CASE_EXPECT_EQ(g_test_coroutine_task_status, 3);
78 
79  CASE_EXPECT_EQ(0, co_another_task->resume(co_another_task.get()));
80  CASE_EXPECT_EQ(g_test_coroutine_task_status, 4);
81 
82  CASE_EXPECT_TRUE(co_task->is_completed());
83  CASE_EXPECT_TRUE(co_another_task->is_completed());
84  CASE_EXPECT_FALSE(co_task->is_canceled());
85  CASE_EXPECT_FALSE(co_task->is_faulted());
86 
87  CASE_EXPECT_GT(0, co_another_task->resume(co_another_task.get()));
88  CASE_EXPECT_EQ(g_test_coroutine_task_status, 4);
89 
90  ++g_test_coroutine_task_status;
91  CASE_EXPECT_EQ(g_test_coroutine_task_status, 5);
92 
93  CASE_EXPECT_NE(co_task->get_id(), 0);
94  }
95 
96  CASE_EXPECT_EQ(g_test_coroutine_task_on_finished, 2);
97 }
98 
99 
100 struct test_context_task_functor {
101 public:
102  int operator()(void *) const {
103  ++g_test_coroutine_task_status;
104  CASE_EXPECT_EQ(g_test_coroutine_task_status, 1);
105 
107 
108  ++g_test_coroutine_task_status;
109  CASE_EXPECT_EQ(g_test_coroutine_task_status, 3);
110 
111  return 0;
112  }
113 };
114 
115 CASE_TEST(coroutine_task, functor_action) {
117  task_ptr_type co_task = cotask::task<>::create(test_context_task_functor());
118  g_test_coroutine_task_status = 0;
119 
120  CASE_EXPECT_EQ(0, co_task->start());
121 
122  ++g_test_coroutine_task_status;
123  CASE_EXPECT_EQ(g_test_coroutine_task_status, 2);
124 
125  CASE_EXPECT_FALSE(co_task->is_completed());
126  CASE_EXPECT_EQ(0, co_task->resume());
127 
128  CASE_EXPECT_TRUE(co_task->is_completed());
129 
130  ++g_test_coroutine_task_status;
131  CASE_EXPECT_EQ(g_test_coroutine_task_status, 4);
132 
133  CASE_EXPECT_NE(co_task->get_id(), 0);
134 }
135 
136 
137 static int test_context_task_function_1(void *) {
138  ++g_test_coroutine_task_status;
139  CASE_EXPECT_EQ(g_test_coroutine_task_status, 1);
140 
142 
143  ++g_test_coroutine_task_status;
144  CASE_EXPECT_EQ(g_test_coroutine_task_status, 3);
145 
146  return 100;
147 }
148 
149 static void test_context_task_function_2(void *) {
150  ++g_test_coroutine_task_status;
151  CASE_EXPECT_EQ(g_test_coroutine_task_status, 1);
152 
154 
155  ++g_test_coroutine_task_status;
156  CASE_EXPECT_EQ(g_test_coroutine_task_status, 3);
157 }
158 
159 CASE_TEST(coroutine_task, function_action) {
160  {
162  task_ptr_type co_task = cotask::task<>::create(test_context_task_function_1);
163  g_test_coroutine_task_status = 0;
164 
165  CASE_EXPECT_EQ(0, co_task->start());
166 
167  ++g_test_coroutine_task_status;
168  CASE_EXPECT_EQ(g_test_coroutine_task_status, 2);
169 
170  CASE_EXPECT_FALSE(co_task->is_completed());
171  CASE_EXPECT_EQ(0, co_task->resume());
172 
173  CASE_EXPECT_TRUE(co_task->is_completed());
174 
175  ++g_test_coroutine_task_status;
176  CASE_EXPECT_EQ(g_test_coroutine_task_status, 4);
177  CASE_EXPECT_EQ(co_task->get_coroutine_context()->get_ret_code(), 100);
178  }
179 
180  {
182  task_ptr_type co_task = cotask::task<>::create(test_context_task_function_2);
183  g_test_coroutine_task_status = 0;
184 
185  CASE_EXPECT_EQ(0, co_task->start());
186 
187  ++g_test_coroutine_task_status;
188  CASE_EXPECT_EQ(g_test_coroutine_task_status, 2);
189 
190  CASE_EXPECT_FALSE(co_task->is_completed());
191  CASE_EXPECT_EQ(0, co_task->resume());
192 
193  CASE_EXPECT_TRUE(co_task->is_completed());
194 
195  ++g_test_coroutine_task_status;
196  CASE_EXPECT_EQ(g_test_coroutine_task_status, 4);
197  }
198 }
199 
200 CASE_TEST(coroutine_task, cancel) {
202  task_ptr_type co_task = cotask::task<>::create(test_context_task_function_1);
203  g_test_coroutine_task_status = 0;
204 
205  CASE_EXPECT_EQ(0, co_task->start());
206 
207  ++g_test_coroutine_task_status;
208  CASE_EXPECT_EQ(g_test_coroutine_task_status, 2);
209 
210  CASE_EXPECT_FALSE(co_task->is_completed());
211  CASE_EXPECT_EQ(0, co_task->cancel(UTIL_CONFIG_NULLPTR));
212 
213  CASE_EXPECT_TRUE(co_task->is_completed());
214 }
215 
216 // task start and coroutine context yield
217 static void test_context_task_function_3(void *) {
218  ++g_test_coroutine_task_status;
219  CASE_EXPECT_EQ(g_test_coroutine_task_status, 1);
220 
222 
224 
226 
227  ++g_test_coroutine_task_status;
228  CASE_EXPECT_EQ(g_test_coroutine_task_status, 3);
229 }
230 
231 CASE_TEST(coroutine_task, coroutine_context_yield) {
233  task_ptr_type co_task = cotask::task<>::create(test_context_task_function_3);
234  g_test_coroutine_task_status = 0;
235 
236  CASE_EXPECT_EQ(0, co_task->start());
237 
238  ++g_test_coroutine_task_status;
239  CASE_EXPECT_EQ(g_test_coroutine_task_status, 2);
240 
241  CASE_EXPECT_FALSE(co_task->is_completed());
242  CASE_EXPECT_EQ(cotask::EN_TS_WAITING, co_task->get_status());
243  CASE_EXPECT_EQ(0, co_task->resume());
244 
245  CASE_EXPECT_TRUE(co_task->is_completed());
246 
247  ++g_test_coroutine_task_status;
248  CASE_EXPECT_EQ(g_test_coroutine_task_status, 4);
249 
250  CASE_EXPECT_NE(co_task->get_id(), 0);
251 }
252 
253 
254 struct test_context_task_mem_function {
255  cotask::task<>::id_t task_id_;
256 
257  int real_run(void *) {
258  ++g_test_coroutine_task_status;
259  CASE_EXPECT_EQ(g_test_coroutine_task_status, 1);
260 
261  CASE_EXPECT_EQ(task_id_, cotask::task<>::this_task()->get_id());
263  CASE_EXPECT_EQ(task_id_, cotask::task<>::this_task()->get_id());
264 
265  ++g_test_coroutine_task_status;
266  CASE_EXPECT_EQ(g_test_coroutine_task_status, 3);
267 
268  return -1;
269  }
270 };
271 
272 CASE_TEST(coroutine_task, mem_function_action) {
274  test_context_task_mem_function obj;
275  task_ptr_type co_task = cotask::task<>::create(&test_context_task_mem_function::real_run, &obj);
276  g_test_coroutine_task_status = 0;
277  obj.task_id_ = co_task->get_id();
278 
279  CASE_EXPECT_EQ(0, co_task->start());
280 
281  ++g_test_coroutine_task_status;
282  CASE_EXPECT_EQ(g_test_coroutine_task_status, 2);
283 
284  CASE_EXPECT_FALSE(co_task->is_completed());
285  CASE_EXPECT_EQ(0, co_task->resume());
286 
287  CASE_EXPECT_TRUE(co_task->is_completed());
288 
289  ++g_test_coroutine_task_status;
290  CASE_EXPECT_EQ(g_test_coroutine_task_status, 4);
291 
292  CASE_EXPECT_NE(co_task->get_coroutine_context()->get_ret_code(), -1);
293 }
294 
295 CASE_TEST(coroutine_task, auto_finish) {
297  {
298  test_context_task_mem_function obj;
299  task_ptr_type co_task = cotask::task<>::create(&test_context_task_mem_function::real_run, &obj);
300  g_test_coroutine_task_status = 0;
301  obj.task_id_ = co_task->get_id();
302  }
303  CASE_EXPECT_EQ(0, g_test_coroutine_task_status);
304 
305  {
306  test_context_task_mem_function obj;
307  task_ptr_type co_task = cotask::task<>::create(&test_context_task_mem_function::real_run, &obj);
308  g_test_coroutine_task_status = 0;
309  obj.task_id_ = co_task->get_id();
310 
311  CASE_EXPECT_EQ(0, co_task->start());
312 
313  ++g_test_coroutine_task_status;
314  CASE_EXPECT_EQ(g_test_coroutine_task_status, 2);
315 
316  CASE_EXPECT_FALSE(co_task->is_completed());
317  }
318 
319  ++g_test_coroutine_task_status;
320  CASE_EXPECT_EQ(g_test_coroutine_task_status, 4);
321 }
322 
323 struct test_context_task_next_action : public cotask::impl::task_action_impl {
324  int set_;
325  int check_;
326  test_context_task_next_action(int s, int c) : cotask::impl::task_action_impl(), set_(s), check_(c) {}
327 
328  int operator()(void *) {
329  CASE_EXPECT_EQ(g_test_coroutine_task_status, check_);
330  g_test_coroutine_task_status = set_;
331 
333 
334  ++g_test_coroutine_task_on_finished;
335  return 0;
336  }
337 };
338 
339 CASE_TEST(coroutine_task, next) {
341 
342  {
343  g_test_coroutine_task_status = 0;
344 
345  task_ptr_type co_task = cotask::task<>::create(test_context_task_next_action(15, 0));
346  co_task->next(test_context_task_next_action(7, 15))
347  ->next(test_context_task_next_action(99, 7))
348  ->next(test_context_task_next_action(1023, 99))
349  ->next(test_context_task_next_action(5, 1023));
350 
351  CASE_EXPECT_EQ(co_task->next(co_task), co_task);
352  CASE_EXPECT_EQ(0, co_task->start());
353  CASE_EXPECT_EQ(g_test_coroutine_task_status, 5);
354 
356  }
357 
358  {
359  g_test_coroutine_task_status = 0;
360  task_ptr_type co_task_a = cotask::task<>::create(test_context_task_next_action(2, 1));
361  task_ptr_type co_task_b = cotask::task<>::create(test_context_task_function_1);
362 
363  CASE_EXPECT_EQ(0, co_task_b->start());
364  co_task_a->next(co_task_b);
365  CASE_EXPECT_EQ(0, co_task_a->start());
366  CASE_EXPECT_TRUE(co_task_a->is_completed());
367  CASE_EXPECT_TRUE(co_task_b->is_completed());
368  CASE_EXPECT_TRUE(co_task_b->::cotask::impl::task_impl::is_completed());
369  }
370 }
371 
372 #if defined(UTIL_CONFIG_COMPILER_CXX_VARIADIC_TEMPLATES) && UTIL_CONFIG_COMPILER_CXX_VARIADIC_TEMPLATES
373 
374 struct test_context_task_functor_drived : public cotask::impl::task_action_impl {
375 public:
376  int a_;
377  int b_;
378  test_context_task_functor_drived(int a, int b) : a_(a), b_(b) {}
379 
380  virtual int operator()(void *) {
381  CASE_EXPECT_EQ(a_, 1);
382  CASE_EXPECT_EQ(3, b_);
383 
384  return 0;
385  }
386 };
387 
388 CASE_TEST(coroutine_task, functor_drived_action) {
391  task_ptr_type co_task = cotask::task<>::create_with<test_context_task_functor_drived>(alloc, 0, 0, 1, 3);
392  CASE_EXPECT_EQ(0, co_task->start());
393 }
394 
395 #endif
396 
397 
398 static int test_context_task_priavte_buffer(void *) {
399 
400  void * priv_data = cotask::task<>::this_task()->get_private_buffer();
402 
403 
404  CASE_EXPECT_GE(priv_sz, 256);
405 
406  if (priv_sz >= 256) {
407  char checked_data[256];
408  memset(checked_data, 0x5e, 256);
409 
410  CASE_EXPECT_EQ(0, memcmp(priv_data, checked_data, 256));
411  }
412 
413  return 0;
414 }
415 
416 CASE_TEST(coroutine_task, priavte_buffer) {
418  task_ptr_type co_task = cotask::task<>::create(test_context_task_priavte_buffer, 16384, 256);
419 
420  void *priv_data = co_task->get_private_buffer();
421  memset(priv_data, 0x5e, 256);
422 
423  CASE_EXPECT_EQ(0, co_task->start());
424 }
425 
426 static int test_context_task_timeout(void *) {
427 
429 
432  CASE_EXPECT_FALSE(cotask::task<>::this_task()->is_completed());
434 
435  return 0;
436 }
437 
438 CASE_TEST(coroutine_task, kill_and_timeout) {
440  task_ptr_type co_task = cotask::task<>::create(test_context_task_timeout, 16384, 256);
441 
442  void *priv_data = co_task->get_private_buffer();
443  memset(priv_data, 0x5e, 256);
444 
445  CASE_EXPECT_EQ(0, co_task->start());
446 
447  CASE_EXPECT_FALSE(co_task->is_timeout());
448  CASE_EXPECT_FALSE(co_task->is_faulted());
449  CASE_EXPECT_FALSE(co_task->is_completed());
450  CASE_EXPECT_FALSE(co_task->is_exiting());
451 
452  CASE_EXPECT_EQ(0, co_task->kill(cotask::EN_TS_TIMEOUT, NULL));
453 
454  CASE_EXPECT_TRUE(co_task->is_completed());
455 
456  CASE_EXPECT_NE(NULL, co_task->get_raw_action());
457 }
458 
459 
460 static int test_context_task_await_1(void *) {
461 
463 
464  task_ptr_type self = cotask::task<>::this_task();
465 
466  CASE_EXPECT_EQ(copp::COPP_EC_ARGS_ERROR, self->await(NULL));
468 
469 
470  void * priv_data = self->get_private_buffer();
471  cotask::task<>::self_t *other_task = *reinterpret_cast<cotask::task<>::self_t **>(priv_data);
472 
473 
474  if (other_task->is_exiting()) {
475  CASE_EXPECT_EQ(copp::COPP_EC_TASK_IS_EXITING, self->await(other_task));
476  } else {
477  if (self->is_exiting()) {
478  CASE_EXPECT_EQ(copp::COPP_EC_TASK_IS_EXITING, self->await(other_task));
479  } else {
480  CASE_EXPECT_EQ(0, self->await(other_task));
481  }
482  }
483 
484  return 0;
485 }
486 
487 static int test_context_task_await_2(void *) { return 0; }
488 
489 CASE_TEST(coroutine_task, await) {
491 
492  // normal
493  {
494  task_ptr_type co_task_1 = cotask::task<>::create(test_context_task_await_1, 16384, sizeof(cotask::task<>::self_t *));
495  task_ptr_type co_task_2 = cotask::task<>::create(test_context_task_await_2, 16384);
496 
497  void *priv_data = co_task_1->get_private_buffer();
498 
499  *reinterpret_cast<cotask::task<>::self_t **>(priv_data) = co_task_2.get();
500  CASE_EXPECT_EQ(copp::COPP_EC_TASK_NOT_IN_ACTION, co_task_1->await(co_task_2));
501 
502  CASE_EXPECT_FALSE(co_task_1->is_exiting());
503  CASE_EXPECT_FALSE(co_task_2->is_exiting());
504 
505  co_task_1->start();
506  CASE_EXPECT_FALSE(co_task_1->is_exiting());
507  CASE_EXPECT_FALSE(co_task_2->is_exiting());
508 
509  co_task_2->start();
510  CASE_EXPECT_TRUE(co_task_1->is_exiting());
511  CASE_EXPECT_TRUE(co_task_2->is_exiting());
512  }
513 
514  // co_task_1 exiting
515  {
516  task_ptr_type co_task_1 = cotask::task<>::create(test_context_task_await_1, 16384, sizeof(cotask::task<>::self_t *));
517  task_ptr_type co_task_2 = cotask::task<>::create(test_context_task_await_2, 16384);
518 
519  void *priv_data = co_task_1->get_private_buffer();
520 
521  CASE_EXPECT_EQ(copp::COPP_EC_ARGS_ERROR, co_task_1->await(UTIL_CONFIG_NULLPTR));
522  CASE_EXPECT_EQ(copp::COPP_EC_TASK_CAN_NOT_WAIT_SELF, co_task_1->await(co_task_1));
523 
524  *reinterpret_cast<cotask::task<>::self_t **>(priv_data) = co_task_2.get();
525  CASE_EXPECT_EQ(copp::COPP_EC_TASK_NOT_IN_ACTION, co_task_1->await(co_task_2));
526 
527  CASE_EXPECT_FALSE(co_task_1->is_exiting());
528  CASE_EXPECT_FALSE(co_task_2->is_exiting());
529 
530  co_task_1->kill(cotask::EN_TS_TIMEOUT);
531  CASE_EXPECT_TRUE(co_task_1->is_exiting());
532  co_task_1->start();
533  CASE_EXPECT_TRUE(co_task_1->is_exiting());
534  CASE_EXPECT_FALSE(co_task_2->is_exiting());
535 
536  co_task_2->start();
537  CASE_EXPECT_TRUE(co_task_1->is_exiting());
538  CASE_EXPECT_TRUE(co_task_2->is_exiting());
539  }
540 
541  // co_task_2 exiting
542  {
543  task_ptr_type co_task_1 = cotask::task<>::create(test_context_task_await_1, 16384, sizeof(cotask::task<>::self_t *));
544  task_ptr_type co_task_2 = cotask::task<>::create(test_context_task_await_2, 16384);
545 
546  void *priv_data = co_task_1->get_private_buffer();
547 
548  *reinterpret_cast<cotask::task<>::self_t **>(priv_data) = co_task_2.get();
549  CASE_EXPECT_EQ(copp::COPP_EC_TASK_NOT_IN_ACTION, co_task_1->await(co_task_2));
550 
551  CASE_EXPECT_FALSE(co_task_1->is_exiting());
552  CASE_EXPECT_FALSE(co_task_2->is_exiting());
553 
554  co_task_2->start();
555  CASE_EXPECT_FALSE(co_task_1->is_exiting());
556  CASE_EXPECT_TRUE(co_task_2->is_exiting());
557 
558  co_task_1->start();
559  CASE_EXPECT_TRUE(co_task_1->is_exiting());
560  CASE_EXPECT_TRUE(co_task_2->is_exiting());
561  }
562 }
563 
564 static int test_context_task_then_action_func(void *priv_data) {
565  CASE_EXPECT_EQ(&g_test_coroutine_task_status, priv_data);
566  ++g_test_coroutine_task_on_finished;
567  return 0;
568 }
569 
570 CASE_TEST(coroutine_task, then) {
572  g_test_coroutine_task_status = 0;
573  g_test_coroutine_task_on_finished = 0;
574 
575  task_ptr_type co_task = cotask::task<>::create(test_context_task_next_action(15, 0));
576  co_task->then(test_context_task_next_action(7, 15))
577  ->then(test_context_task_next_action(99, 7))
578  ->then(test_context_task_next_action(1023, 99))
579  ->then(test_context_task_next_action(5, 1023));
580 
581 
582  CASE_EXPECT_EQ(0, co_task->start());
583  CASE_EXPECT_EQ(g_test_coroutine_task_status, 5);
584 
586 
587  CASE_EXPECT_TRUE(co_task->is_exiting());
588  CASE_EXPECT_TRUE(co_task->is_completed());
589 
590  co_task->then(test_context_task_next_action(127, 5))->then(test_context_task_then_action_func, &g_test_coroutine_task_status);
591  CASE_EXPECT_EQ(g_test_coroutine_task_status, 127);
592  CASE_EXPECT_EQ(g_test_coroutine_task_on_finished, 7);
593 }
594 
595 
596 typedef copp::stack_pool<copp::allocator::stack_allocator_malloc> test_context_task_stack_pool_t;
597 struct test_context_task_stack_pool_test_macro_coroutine {
599 
601 };
602 
603 typedef cotask::task<test_context_task_stack_pool_test_macro_coroutine> test_context_task_stack_pool_test_task_t;
604 
605 CASE_TEST(coroutine_task, then_with_stack_pool) {
606  typedef test_context_task_stack_pool_test_task_t::ptr_t task_ptr_type;
607  test_context_task_stack_pool_t::ptr_t stack_pool = test_context_task_stack_pool_t::create();
608 
609  g_test_coroutine_task_on_finished = 0;
610  g_test_coroutine_task_status = 0;
611 
613  task_ptr_type tp = test_context_task_stack_pool_test_task_t::create(test_context_task_next_action(15, 0), base_alloc);
614  tp->then(test_context_task_next_action(127, 15))->then(test_context_task_then_action_func, &g_test_coroutine_task_status);
615 
616  CASE_EXPECT_EQ(3, stack_pool->get_limit().used_stack_number);
617  tp->start();
618  CASE_EXPECT_EQ(1, stack_pool->get_limit().used_stack_number);
619 
620  tp->then(test_context_task_next_action(255, 127))->then(test_context_task_then_action_func, &g_test_coroutine_task_status);
621 
622  CASE_EXPECT_EQ(1, stack_pool->get_limit().used_stack_number);
623  CASE_EXPECT_EQ(g_test_coroutine_task_status, 255);
624  CASE_EXPECT_EQ(g_test_coroutine_task_on_finished, 5);
625 }
626 
627 #endif
#define CASE_TEST(test_name, case_name)
Definition: test_macros.h:43
#define CASE_EXPECT_GT(l, r)
Definition: test_macros.h:66
virtual int operator()(void *)=0
COPP_EC_TASK_IS_EXITING.
Definition: errno.h:36
COPP_EC_TASK_CAN_NOT_WAIT_SELF.
Definition: errno.h:35
size_t get_private_buffer_size()
Definition: task.h:605
COPP_EC_ALREADY_FINISHED.
Definition: errno.h:27
bool is_exiting() const UTIL_CONFIG_NOEXCEPT
check if a cotask is exiting
Definition: task_impl.cpp:34
#define CASE_EXPECT_EQ(l, r)
Definition: test_macros.h:62
#define CASE_EXPECT_TRUE(c)
Definition: test_macros.h:60
virtual int yield(void **priv_data) UTIL_CONFIG_OVERRIDE
Definition: task.h:531
COPP_EC_IS_RUNNING.
Definition: errno.h:26
Tt * get()
get current running task and try to convert type
Definition: this_task.h:31
static ptr_t create(const Ty &functor, size_t stack_size=0, size_t private_buffer_size=0)
create task with functor
Definition: task.h:162
macro_task_t::id_t id_t
Definition: task.h:38
int yield(void **priv_data=UTIL_CONFIG_NULLPTR)
yield current coroutine
#define CASE_EXPECT_NE(l, r)
Definition: test_macros.h:63
导入智能指针库 Licensed under the MIT licenses.
#define CASE_EXPECT_GE(l, r)
Definition: test_macros.h:67
coroutine container contain stack context, stack allocator and runtime fcontext
impl::task_impl * get_task() UTIL_CONFIG_NOEXCEPT
get current running task
Definition: this_task.cpp:15
COPP_EC_TASK_NOT_IN_ACTION.
Definition: errno.h:38
static self_t * this_task()
Definition: task.h:444
element_type * get() const UTIL_CONFIG_NOEXCEPT
void * get_private_buffer()
Definition: task.h:597
memory allocator this allocator will maintain buffer using malloc/free function
virtual int on_finished(task_impl &)
#define CASE_EXPECT_FALSE(c)
Definition: test_macros.h:61
virtual int yield(void **priv_data)=0
my_task_t::ptr_t task_ptr_type
COPP_EC_ARGS_ERROR.
Definition: errno.h:30