libcopp 2.3.1
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
21LIBCOPP_COTASK_NAMESPACE_BEGIN
22namespace impl {
23LIBCOPP_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
30LIBCOPP_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
39LIBCOPP_COTASK_API bool task_impl::is_canceled() const LIBCOPP_MACRO_NOEXCEPT { return EN_TS_CANCELED == get_status(); }
40
41LIBCOPP_COTASK_API bool task_impl::is_completed() const LIBCOPP_MACRO_NOEXCEPT { return is_exiting(); }
42
43LIBCOPP_COTASK_API bool task_impl::is_faulted() const LIBCOPP_MACRO_NOEXCEPT { return EN_TS_KILLED <= get_status(); }
44
45LIBCOPP_COTASK_API bool task_impl::is_timeout() const LIBCOPP_MACRO_NOEXCEPT { return EN_TS_TIMEOUT == get_status(); }
46
47LIBCOPP_COTASK_API bool task_impl::is_exiting() const LIBCOPP_MACRO_NOEXCEPT { return EN_TS_DONE <= get_status(); }
48
49LIBCOPP_COTASK_API int task_impl::on_finished() { return 0; }
50
51LIBCOPP_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
65LIBCOPP_COTASK_API void task_impl::_set_action(action_ptr_type action) { action_ = action; }
66
68
69LIBCOPP_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,
73 LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_acquire);
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
79LIBCOPP_COTASK_API int task_impl::_notify_finished(std::list<std::exception_ptr> &unhandled, void *priv_data) {
80#else
81LIBCOPP_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());
94 return LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_HAS_UNHANDLE_EXCEPTION;
95 }
96#else
97 return ret;
98#endif
99}
100} // namespace impl
101LIBCOPP_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:49
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_COTASK_API task_impl()
Definition task_impl.cpp:23
LIBCOPP_COPP_NAMESPACE_ID::util::lock::atomic_int_type< LIBCOPP_COPP_NAMESPACE_ID::util::lock::unsafe_int_type< uint32_t > > status_
Definition task_impl.h:161
LIBCOPP_UTIL_FORCEINLINE EN_TASK_STATUS get_status() const LIBCOPP_MACRO_NOEXCEPT
Definition task_impl.h:82
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
void * finish_priv_data_
Definition task_impl.h:153
LIBCOPP_COTASK_API action_ptr_type _get_action()
Definition task_impl.cpp:67
action_ptr_type action_
Definition task_impl.h:149
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
EN_TASK_STATUS
Definition task_impl.h:29
@ EN_TS_DONE
Definition task_impl.h:34
@ EN_TS_CREATED
Definition task_impl.h:31
@ EN_TS_TIMEOUT
Definition task_impl.h:37
@ EN_TS_KILLED
Definition task_impl.h:36
@ EN_TS_CANCELED
Definition task_impl.h:35