libcopp  2.2.0
task_impl.cpp
Go to the documentation of this file.
1 // Copyright 2023 owent
2 
3 #include <libcopp/utils/config/libcopp_build_features.h>
4 
7 
10 
11 // clang-format off
12 #include <libcopp/utils/config/stl_include_prefix.h> // NOLINT(build/include_order)
13 // clang-format on
14 #include <assert.h>
15 #include <algorithm>
16 #include <cstdlib>
17 // clang-format off
18 #include <libcopp/utils/config/stl_include_suffix.h> // NOLINT(build/include_order)
19 // clang-format on
20 
21 LIBCOPP_COTASK_NAMESPACE_BEGIN
22 namespace impl {
23 LIBCOPP_COTASK_API task_impl::task_impl()
24  : action_(nullptr), id_(0), finish_priv_data_(nullptr), status_(EN_TS_CREATED) {
25  id_allocator_t id_alloc_;
26  ((void)id_alloc_);
27  id_ = id_alloc_.allocate();
28 }
29 
30 LIBCOPP_COTASK_API task_impl::~task_impl() {
31  assert(status_ <= EN_TS_CREATED || status_ >= EN_TS_DONE);
32 
33  // free resource
34  id_allocator_t id_alloc_;
35  ((void)id_alloc_);
36  id_alloc_.deallocate(id_);
37 }
38 
39 LIBCOPP_COTASK_API bool task_impl::is_canceled() const LIBCOPP_MACRO_NOEXCEPT { return EN_TS_CANCELED == get_status(); }
40 
41 LIBCOPP_COTASK_API bool task_impl::is_completed() const LIBCOPP_MACRO_NOEXCEPT { return is_exiting(); }
42 
43 LIBCOPP_COTASK_API bool task_impl::is_faulted() const LIBCOPP_MACRO_NOEXCEPT { return EN_TS_KILLED <= get_status(); }
44 
45 LIBCOPP_COTASK_API bool task_impl::is_timeout() const LIBCOPP_MACRO_NOEXCEPT { return EN_TS_TIMEOUT == get_status(); }
46 
47 LIBCOPP_COTASK_API bool task_impl::is_exiting() const LIBCOPP_MACRO_NOEXCEPT { return EN_TS_DONE <= get_status(); }
48 
49 LIBCOPP_COTASK_API int task_impl::on_finished() { return 0; }
50 
51 LIBCOPP_COTASK_API task_impl *task_impl::this_task() {
52  LIBCOPP_COPP_NAMESPACE_ID::coroutine_context_base *this_co =
53  LIBCOPP_COPP_NAMESPACE_ID::coroutine_context_base::get_this_coroutine_base();
54  if (nullptr == this_co) {
55  return nullptr;
56  }
57 
58  if (false == this_co->check_flags(ext_coroutine_flag_t::EN_ECFT_COTASK)) {
59  return nullptr;
60  }
61 
62  return *reinterpret_cast<task_impl **>(this_co->get_private_buffer());
63 }
64 
66 
68 
69 LIBCOPP_COTASK_API bool task_impl::_cas_status(EN_TASK_STATUS &expected, EN_TASK_STATUS desired) {
70  uint32_t expected_int = expected;
71  bool ret =
72  status_.compare_exchange_weak(expected_int, desired, LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_acq_rel,
74  expected = static_cast<EN_TASK_STATUS>(expected_int);
75  return ret;
76 }
77 
78 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
79 LIBCOPP_COTASK_API int task_impl::_notify_finished(std::list<std::exception_ptr> &unhandled, void *priv_data) {
80 #else
81 LIBCOPP_COTASK_API int task_impl::_notify_finished(void *priv_data) {
82 #endif
83  finish_priv_data_ = priv_data;
84 
85 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
86  try {
87 #endif
88  _get_action()->on_finished(*this);
89  int ret = on_finished();
90 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
91  return ret;
92  } catch (...) {
93  unhandled.emplace_back(std::current_exception());
95  }
96 #else
97  return ret;
98 #endif
99 }
100 } // namespace impl
101 LIBCOPP_COTASK_NAMESPACE_END
virtual int on_finished(task_impl &)
virtual LIBCOPP_COTASK_API bool is_timeout() const LIBCOPP_MACRO_NOEXCEPT
Definition: task_impl.cpp:45
id_allocator_type id_allocator_t
Definition: task_impl.h:47
LIBCOPP_COTASK_API bool is_exiting() const LIBCOPP_MACRO_NOEXCEPT
check if a cotask is exiting
Definition: task_impl.cpp:47
virtual LIBCOPP_COTASK_API bool is_faulted() const LIBCOPP_MACRO_NOEXCEPT
Definition: task_impl.cpp:43
LIBCOPP_COPP_NAMESPACE_ID::util::lock::atomic_int_type< uint32_t > status_
Definition: task_impl.h:155
LIBCOPP_COTASK_API task_impl()
Definition: task_impl.cpp:23
LIBCOPP_COTASK_API void _set_action(action_ptr_type action)
Definition: task_impl.cpp:65
virtual LIBCOPP_COTASK_API bool is_canceled() const LIBCOPP_MACRO_NOEXCEPT
Definition: task_impl.cpp:39
virtual LIBCOPP_COTASK_API int on_finished()
Definition: task_impl.cpp:49
UTIL_FORCEINLINE EN_TASK_STATUS get_status() const LIBCOPP_MACRO_NOEXCEPT
Definition: task_impl.h:80
void * finish_priv_data_
Definition: task_impl.h:151
LIBCOPP_COTASK_API action_ptr_type _get_action()
Definition: task_impl.cpp:67
action_ptr_type action_
Definition: task_impl.h:147
virtual LIBCOPP_COTASK_API ~task_impl()=0
Definition: task_impl.cpp:30
virtual LIBCOPP_COTASK_API bool is_completed() const LIBCOPP_MACRO_NOEXCEPT
Definition: task_impl.cpp:41
LIBCOPP_COTASK_API bool _cas_status(EN_TASK_STATUS &expected, EN_TASK_STATUS desired)
Definition: task_impl.cpp:69
static LIBCOPP_COTASK_API task_impl * this_task()
Definition: task_impl.cpp:51
LIBCOPP_COTASK_API int _notify_finished(void *priv_data)
Definition: task_impl.cpp:81
@ COPP_EC_HAS_UNHANDLE_EXCEPTION
COPP_EC_CAST_FAILED.
Definition: errno.h:32
EN_TASK_STATUS
Definition: task_impl.h:27
@ EN_TS_DONE
Definition: task_impl.h:32
@ EN_TS_CREATED
Definition: task_impl.h:29
@ EN_TS_TIMEOUT
Definition: task_impl.h:35
@ EN_TS_KILLED
Definition: task_impl.h:34
@ EN_TS_CANCELED
Definition: task_impl.h:33