5 #include <libcopp/utils/config/libcopp_build_features.h>
9 #include <libcopp/utils/config/libcopp_build_features.h>
19 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
23 #if defined(LIBCOPP_MACRO_ENABLE_WIN_FIBER) && LIBCOPP_MACRO_ENABLE_WIN_FIBER
24 # include <type_traits>
34 LIBCOPP_COTASK_NAMESPACE_BEGIN
36 template <
typename TCO_MACRO = macro_coroutine>
41 using ptr_type = LIBCOPP_COPP_NAMESPACE_ID::util::intrusive_ptr<self_type>;
73 : stack_size_(stack_sz),
74 action_destroy_fn_(nullptr)
75 #if defined(LIBCOTASK_MACRO_AUTO_CLEANUP_MANAGER) && LIBCOTASK_MACRO_AUTO_CLEANUP_MANAGER
77 binding_manager_ptr_(nullptr),
78 binding_manager_fn_(nullptr)
90 template <
typename TAct,
typename Ty>
92 typename coroutine_type::allocator_type &alloc,
93 size_t stack_size = 0,
94 size_t private_buffer_size = 0) {
97 if (0 == stack_size) {
98 stack_size = LIBCOPP_COPP_NAMESPACE_ID::stack_traits::default_size();
101 size_t action_size = coroutine_type::align_address_size(
sizeof(a_t));
102 size_t task_size = coroutine_type::align_address_size(
sizeof(
self_type));
104 if (stack_size <=
sizeof(
impl::task_impl *) + private_buffer_size + action_size + task_size) {
108 typename coroutine_type::ptr_type coroutine =
109 coroutine_type::create(
typename coroutine_type::callback_t(), alloc, stack_size,
110 sizeof(
impl::task_impl *) + private_buffer_size, action_size + task_size);
115 void *action_addr = sub_buffer_offset(coroutine.get(), action_size);
116 void *task_addr = sub_buffer_offset(action_addr, task_size);
124 *(
reinterpret_cast<impl::task_impl **
>(coroutine->get_private_buffer())) = ret.get();
125 ret->coroutine_obj_ = coroutine;
135 coroutine->set_runner([
action](
void *private_data) {
return (*
action)(private_data); });
150 template <
typename Ty>
151 static inline ptr_type create(Ty &&functor,
size_t stack_size = 0,
size_t private_buffer_size = 0) {
152 typename coroutine_type::allocator_type alloc;
153 return create(std::forward<Ty>(functor), alloc, stack_size, private_buffer_size);
156 template <
typename Ty>
157 static inline ptr_type create(Ty &&functor,
typename coroutine_type::allocator_type &alloc,
size_t stack_size = 0,
158 size_t private_buffer_size = 0) {
159 using decay_type =
typename std::decay<Ty>::type;
160 using a_t =
typename std::conditional<std::is_base_of<impl::task_action_impl, decay_type>::value, decay_type,
163 return create_with_delegate<a_t>(std::forward<Ty>(functor), alloc, stack_size, private_buffer_size);
172 template <
typename Ty>
173 static inline ptr_type create(Ty (*func)(
void *),
typename coroutine_type::allocator_type &alloc,
174 size_t stack_size = 0,
size_t private_buffer_size = 0) {
177 return create_with_delegate<a_t>(func, alloc, stack_size, private_buffer_size);
180 template <
typename Ty>
181 static inline ptr_type create(Ty (*func)(
void *),
size_t stack_size = 0,
size_t private_buffer_size = 0) {
182 typename coroutine_type::allocator_type alloc;
183 return create(func, alloc, stack_size, private_buffer_size);
192 template <
typename Ty,
typename TInst>
193 static LIBCOPP_COTASK_API_HEAD_ONLY
ptr_type create(Ty(TInst::*func), TInst *instance,
194 typename coroutine_type::allocator_type &alloc,
195 size_t stack_size = 0,
size_t private_buffer_size = 0) {
198 return create<a_t>(a_t(func, instance), alloc, stack_size, private_buffer_size);
201 template <
typename Ty,
typename TInst>
202 static inline ptr_type create(Ty(TInst::*func), TInst *instance,
size_t stack_size = 0,
203 size_t private_buffer_size = 0) {
204 typename coroutine_type::allocator_type alloc;
205 return create(func, instance, alloc, stack_size, private_buffer_size);
214 template <
typename Ty,
typename... TParams>
216 size_t stack_size,
size_t private_buffer_size,
220 return create(a_t(std::forward<TParams>(args)...), alloc, stack_size, private_buffer_size);
233 if (
this == next_task.get() || !next_task) {
242 next_task->start(priv_data);
244 next_task->resume(priv_data);
249 #if !defined(LIBCOPP_DISABLE_ATOMIC_LOCK) || !(LIBCOPP_DISABLE_ATOMIC_LOCK)
250 LIBCOPP_COPP_NAMESPACE_ID::util::lock::lock_holder<LIBCOPP_COPP_NAMESPACE_ID::util::lock::spin_lock> lock_guard(
254 next_list_.member_list_.push_back(std::make_pair(next_task, priv_data));
266 template <
typename Ty>
267 inline ptr_type next(Ty &&functor,
void *priv_data =
nullptr,
size_t stack_size = 0,
size_t private_buffer_size = 0) {
268 return next(create(std::forward<Ty>(functor), stack_size, private_buffer_size), priv_data);
271 template <
typename Ty>
272 inline ptr_type next(Ty &&functor,
typename coroutine_type::allocator_type &alloc,
void *priv_data =
nullptr,
273 size_t stack_size = 0,
size_t private_buffer_size = 0) {
274 return next(create(std::forward<Ty>(functor), alloc, stack_size, private_buffer_size), priv_data);
285 template <
typename Ty>
286 inline ptr_type next(Ty (*func)(
void *),
void *priv_data =
nullptr,
size_t stack_size = 0,
287 size_t private_buffer_size = 0) {
288 return next(create(func, stack_size, private_buffer_size), priv_data);
291 template <
typename Ty>
292 inline ptr_type next(Ty (*func)(
void *),
typename coroutine_type::allocator_type &alloc,
void *priv_data =
nullptr,
293 size_t stack_size = 0,
size_t private_buffer_size = 0) {
294 return next(create(func, alloc, stack_size, private_buffer_size), priv_data);
306 template <
typename Ty,
typename TInst>
307 inline ptr_type next(Ty(TInst::*func), TInst *instance,
void *priv_data =
nullptr,
size_t stack_size = 0,
308 size_t private_buffer_size = 0) {
309 return next(create(func, instance, stack_size, private_buffer_size), priv_data);
312 template <
typename Ty,
typename TInst>
313 inline ptr_type next(Ty(TInst::*func), TInst *instance,
typename coroutine_type::allocator_type &alloc,
314 void *priv_data =
nullptr,
size_t stack_size = 0,
size_t private_buffer_size = 0) {
315 return next(create(func, instance, alloc, stack_size, private_buffer_size), priv_data);
331 if (
this == wait_task.get()) {
336 if (wait_task->is_exiting() || wait_task->is_completed()) {
349 if (wait_task->next(
ptr_type(
this)).
get() !=
this) {
354 while (!(wait_task->is_exiting() || wait_task->is_completed())) {
365 template <
typename TTask>
367 return await_task(
ptr_type(wait_task));
387 template <
typename Ty>
389 if (!coroutine_obj_) {
390 then(create(std::forward<Ty>(functor), stack_size_, get_private_buffer_size()), priv_data);
394 create(std::forward<Ty>(functor), coroutine_obj_->get_allocator(), stack_size_, get_private_buffer_size()),
398 template <
typename Ty>
400 if (!coroutine_obj_) {
401 return then(create(func, stack_size_, get_private_buffer_size()), priv_data);
404 return then(create(func, coroutine_obj_->get_allocator(), stack_size_, get_private_buffer_size()), priv_data);
412 #if defined(LIBCOPP_MACRO_ENABLE_RTTI) && LIBCOPP_MACRO_ENABLE_RTTI
426 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
427 std::list<std::exception_ptr> eptrs;
428 active_next_tasks(eptrs);
430 maybe_rethrow(eptrs);
439 return coroutine_obj_;
444 if (!coroutine_obj_) {
448 return coroutine_obj_->get_ret_code();
451 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
453 std::list<std::exception_ptr> eptrs;
454 int ret =
start(eptrs, priv_data, expected_status);
455 maybe_rethrow(eptrs);
459 virtual int start(std::list<std::exception_ptr> &unhandled,
void *priv_data,
464 if (!coroutine_obj_) {
487 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
488 std::exception_ptr eptr;
489 int ret = coroutine_obj_->start(eptr, priv_data);
491 unhandled.emplace_back(std::move(eptr));
494 int ret = coroutine_obj_->start(priv_data);
505 finish_priv_data_ = priv_data;
506 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
516 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
533 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
535 return start(priv_data, expected_status);
538 virtual int resume(std::list<std::exception_ptr> &unhandled,
void *priv_data,
540 return start(unhandled, priv_data, expected_status);
544 return start(priv_data, expected_status);
548 int yield(
void **priv_data)
override {
549 if (!coroutine_obj_) {
553 return coroutine_obj_->yield(priv_data);
556 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
557 int cancel(
void *priv_data)
override {
558 std::list<std::exception_ptr> eptrs;
559 int ret =
cancel(eptrs, priv_data);
560 maybe_rethrow(eptrs);
564 virtual int cancel(std::list<std::exception_ptr> &unhandled,
void *priv_data) LIBCOPP_MACRO_NOEXCEPT {
581 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
589 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
591 std::list<std::exception_ptr> eptrs;
592 int ret =
kill(eptrs, status, priv_data);
593 maybe_rethrow(eptrs);
597 virtual int kill(std::list<std::exception_ptr> &unhandled,
enum EN_TASK_STATUS status,
598 void *priv_data) LIBCOPP_MACRO_NOEXCEPT {
611 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
617 finish_priv_data_ = priv_data;
631 if (!coroutine_obj_) {
635 return coroutine_obj_->is_finished();
638 #if defined(LIBCOPP_MACRO_ENABLE_WIN_FIBER) && LIBCOPP_MACRO_ENABLE_WIN_FIBER
639 bool is_fiber()
const LIBCOPP_MACRO_NOEXCEPT
override {
640 return std::is_base_of<LIBCOPP_COPP_NAMESPACE_ID::coroutine_context_fiber, coroutine_type>::value;
645 return reinterpret_cast<void *
>(
reinterpret_cast<unsigned char *
>(in) + off);
649 return reinterpret_cast<void *
>(
reinterpret_cast<unsigned char *
>(in) - off);
653 if (!coroutine_obj_) {
657 return add_buffer_offset(coroutine_obj_->get_private_buffer(),
sizeof(
impl::task_impl *));
661 if (!coroutine_obj_) {
665 return coroutine_obj_->get_private_buffer_size() -
sizeof(
impl::task_impl *);
668 inline size_t use_count()
const {
return ref_count_.load(); }
670 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
671 UTIL_FORCEINLINE static void maybe_rethrow(std::list<std::exception_ptr> &eptrs) {
672 for (std::list<std::exception_ptr>::iterator iter = eptrs.begin(); iter != eptrs.end(); ++iter) {
673 coroutine_type::maybe_rethrow(*iter);
680 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
681 void active_next_tasks(std::list<std::exception_ptr> &unhandled) LIBCOPP_MACRO_NOEXCEPT {
685 std::list<std::pair<ptr_type, void *> > next_list;
686 #if defined(LIBCOTASK_MACRO_AUTO_CLEANUP_MANAGER) && LIBCOTASK_MACRO_AUTO_CLEANUP_MANAGER
692 #if !defined(LIBCOPP_DISABLE_ATOMIC_LOCK) || !(LIBCOPP_DISABLE_ATOMIC_LOCK)
693 LIBCOPP_COPP_NAMESPACE_ID::util::lock::lock_holder<LIBCOPP_COPP_NAMESPACE_ID::util::lock::spin_lock> lock_guard(
696 next_list.swap(next_list_.member_list_);
697 #if defined(LIBCOTASK_MACRO_AUTO_CLEANUP_MANAGER) && LIBCOTASK_MACRO_AUTO_CLEANUP_MANAGER
698 manager_ptr = binding_manager_ptr_;
699 manager_fn = binding_manager_fn_;
700 binding_manager_ptr_ =
nullptr;
701 binding_manager_fn_ =
nullptr;
706 for (
typename std::list<std::pair<ptr_type, void *> >::iterator iter = next_list.begin(); iter != next_list.end();
708 if (!iter->first ||
EN_TS_INVALID == iter->first->get_status()) {
712 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
714 iter->first->start(unhandled, iter->second);
716 iter->first->resume(unhandled, iter->second);
720 iter->first->start(iter->second);
722 iter->first->resume(iter->second);
727 #if defined(LIBCOPP_MACRO_ENABLE_STD_COROUTINE) && LIBCOPP_MACRO_ENABLE_STD_COROUTINE
728 caller_manager_.resume_callers();
732 #if defined(LIBCOTASK_MACRO_AUTO_CLEANUP_MANAGER) && LIBCOTASK_MACRO_AUTO_CLEANUP_MANAGER
733 if (
nullptr != manager_ptr &&
nullptr != manager_fn) {
734 (*manager_fn)(manager_ptr, *
this);
740 #
if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
741 std::list<std::exception_ptr> &unhandled,
743 void *priv_data) LIBCOPP_MACRO_NOEXCEPT {
745 if (coroutine_obj_ &&
false == coroutine_obj_->is_finished()) {
747 while (
false == coroutine_obj_->is_finished()) {
748 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
749 std::exception_ptr eptr;
750 coroutine_obj_->resume(eptr, priv_data);
752 unhandled.emplace_back(std::move(eptr));
755 coroutine_obj_->resume(priv_data);
760 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
763 active_next_tasks(unhandled);
789 using this_coroutine_ptr_type =
typename this_coroutine_type::ptr_type;
793 void *action_ptr =
reinterpret_cast<void *
>(p->
_get_action());
806 #if defined(LIBCOTASK_MACRO_AUTO_CLEANUP_MANAGER) && LIBCOTASK_MACRO_AUTO_CLEANUP_MANAGER
808 class LIBCOPP_COTASK_API_HEAD_ONLY task_manager_helper {
812 static bool setup_task_manager(self_type &task_inst,
void *manager_ptr,
void (*fn)(
void *, self_type &)) {
813 # if !defined(LIBCOPP_DISABLE_ATOMIC_LOCK) || !(LIBCOPP_DISABLE_ATOMIC_LOCK)
814 LIBCOPP_COPP_NAMESPACE_ID::util::lock::lock_holder<LIBCOPP_COPP_NAMESPACE_ID::util::lock::spin_lock> lock_guard(
815 task_inst.inner_action_lock_);
817 if (task_inst.binding_manager_ptr_ !=
nullptr) {
821 task_inst.binding_manager_ptr_ = manager_ptr;
822 task_inst.binding_manager_fn_ = fn;
826 static bool cleanup_task_manager(self_type &task_inst,
void *manager_ptr) {
827 # if !defined(LIBCOPP_DISABLE_ATOMIC_LOCK) || !(LIBCOPP_DISABLE_ATOMIC_LOCK)
828 LIBCOPP_COPP_NAMESPACE_ID::util::lock::lock_holder<LIBCOPP_COPP_NAMESPACE_ID::util::lock::spin_lock> lock_guard(
829 task_inst.inner_action_lock_);
831 if (task_inst.binding_manager_ptr_ != manager_ptr) {
835 task_inst.binding_manager_ptr_ =
nullptr;
836 task_inst.binding_manager_fn_ =
nullptr;
842 #if defined(LIBCOPP_MACRO_ENABLE_STD_COROUTINE) && LIBCOPP_MACRO_ENABLE_STD_COROUTINE
844 class LIBCOPP_COPP_API_HEAD_ONLY stackful_task_awaitable :
public LIBCOPP_COPP_NAMESPACE_ID::awaitable_base_type {
849 explicit stackful_task_awaitable(self_type *waiting_task) : waiting_task_(waiting_task) {}
851 inline bool await_ready()
const noexcept {
852 if (!waiting_task_) {
856 return waiting_task_->is_exiting();
859 # if defined(LIBCOPP_MACRO_ENABLE_CONCEPTS) && LIBCOPP_MACRO_ENABLE_CONCEPTS
860 template <LIBCOPP_COPP_NAMESPACE_ID::DerivedPromiseBaseType TCPROMISE>
862 template <
class TCPROMISE,
typename = std::enable_if_t<
863 std::is_base_of<LIBCOPP_COPP_NAMESPACE_ID::promise_base_type, TCPROMISE>::value> >
866 if (waiting_task_ && !waiting_task_->is_exiting() &&
867 caller.promise().get_status() < LIBCOPP_COPP_NAMESPACE_ID::promise_status::kDone) {
869 waiting_task_->caller_manager_.add_caller(
870 LIBCOPP_COPP_NAMESPACE_ID::promise_caller_manager::handle_delegate{caller});
873 caller.promise().set_flag(LIBCOPP_COPP_NAMESPACE_ID::promise_flag::kInternalWaitting,
true);
881 if (!waiting_task_) {
886 if (waiting_task_->is_exiting()) {
887 switch (waiting_task_->get_status()) {
894 ret = waiting_task_->get_ret_code();
902 auto caller = get_caller();
905 if (
nullptr != caller.promise) {
906 caller.promise->set_flag(LIBCOPP_COPP_NAMESPACE_ID::promise_flag::kInternalWaitting,
false);
909 waiting_task_->caller_manager_.remove_caller(caller);
918 self_type *waiting_task_;
921 auto operator co_await() & LIBCOPP_MACRO_NOEXCEPT {
return stackful_task_awaitable{
this}; }
929 void (*action_destroy_fn_)(
void *);
931 #if !defined(LIBCOPP_DISABLE_ATOMIC_LOCK) || !(LIBCOPP_DISABLE_ATOMIC_LOCK)
932 LIBCOPP_COPP_NAMESPACE_ID::util::lock::atomic_int_type<size_t>
ref_count_;
935 LIBCOPP_COPP_NAMESPACE_ID::util::lock::atomic_int_type<
936 LIBCOPP_COPP_NAMESPACE_ID::util::lock::unsafe_int_type<size_t> >
941 #if defined(LIBCOTASK_MACRO_AUTO_CLEANUP_MANAGER) && LIBCOTASK_MACRO_AUTO_CLEANUP_MANAGER
942 void *binding_manager_ptr_;
943 void (*binding_manager_fn_)(
void *,
self_type &);
946 #if defined(LIBCOPP_MACRO_ENABLE_STD_COROUTINE) && LIBCOPP_MACRO_ENABLE_STD_COROUTINE
947 LIBCOPP_COPP_NAMESPACE_ID::promise_caller_manager caller_manager_;
951 #if defined(LIBCOPP_MACRO_ENABLE_STD_COROUTINE) && LIBCOPP_MACRO_ENABLE_STD_COROUTINE
952 template <
typename TCO_MACRO>
953 auto operator co_await(
const LIBCOPP_COPP_NAMESPACE_ID::util::intrusive_ptr<
task<TCO_MACRO> > &t)
954 LIBCOPP_MACRO_NOEXCEPT {
956 return awaitable{t.get()};
959 LIBCOPP_COTASK_NAMESPACE_END
UTIL_FORCEINLINE int start()
id_allocator_type id_allocator_t
LIBCOPP_COTASK_API bool is_exiting() const LIBCOPP_MACRO_NOEXCEPT
check if a cotask is exiting
LIBCOPP_COPP_NAMESPACE_ID::util::uint64_id_allocator id_allocator_type
UTIL_FORCEINLINE int resume()
task_action_impl * action_ptr_type
UTIL_FORCEINLINE int yield()
LIBCOPP_COPP_NAMESPACE_ID::util::uint64_id_allocator::value_type id_type
UTIL_FORCEINLINE EN_TASK_STATUS get_status() const LIBCOPP_MACRO_NOEXCEPT
UTIL_FORCEINLINE int cancel()
UTIL_FORCEINLINE int kill()
LIBCOPP_COTASK_API action_ptr_type _get_action()
virtual LIBCOPP_COTASK_API bool is_completed() const LIBCOPP_MACRO_NOEXCEPT
LIBCOPP_COTASK_API bool _cas_status(EN_TASK_STATUS &expected, EN_TASK_STATUS desired)
static LIBCOPP_COTASK_API task_impl * this_task()
LIBCOPP_COTASK_API int _notify_finished(void *priv_data)
ptr_type next(Ty &&functor, typename coroutine_type::allocator_type &alloc, void *priv_data=nullptr, size_t stack_size=0, size_t private_buffer_size=0)
size_t get_private_buffer_size()
ptr_type next(Ty(TInst::*func), TInst *instance, void *priv_data=nullptr, size_t stack_size=0, size_t private_buffer_size=0)
create next task with function
static ptr_type create(Ty &&functor, size_t stack_size=0, size_t private_buffer_size=0)
create task with functor
int yield(void **priv_data) override
int _notify_finished(void *priv_data) LIBCOPP_MACRO_NOEXCEPT
stack_allocator_type stack_allocator_t
static ptr_type create(Ty(*func)(void *), size_t stack_size=0, size_t private_buffer_size=0)
const coroutine_type::ptr_type & get_coroutine_context() const LIBCOPP_MACRO_NOEXCEPT
ptr_type next(ptr_type next_task, void *priv_data=nullptr)
add next task to run when task finished
LIBCOPP_COPP_NAMESPACE_ID::util::lock::atomic_int_type< size_t > ref_count_
LIBCOPP_COPP_NAMESPACE_ID::util::lock::spin_lock inner_action_lock_
static ptr_type create(Ty &&functor, typename coroutine_type::allocator_type &alloc, size_t stack_size=0, size_t private_buffer_size=0)
task(size_t stack_sz)
constuctor
int get_ret_code() const override
macro_coroutine_type macro_coroutine_t
friend void intrusive_ptr_release(self_type *p)
int await_task(TTask *wait_task)
ptr_type then(Ty(*func)(void *), void *priv_data=nullptr)
ptr_type next(Ty(*func)(void *), void *priv_data=nullptr, size_t stack_size=0, size_t private_buffer_size=0)
create next task with function
static LIBCOPP_COTASK_API_HEAD_ONLY ptr_type create_with(typename coroutine_type::allocator_type &alloc, size_t stack_size, size_t private_buffer_size, TParams &&...args)
create task with functor type and parameters
int kill(enum EN_TASK_STATUS status, void *priv_data) override
static void * add_buffer_offset(void *in, size_t off)
static self_type * this_task()
coroutine_type::ptr_type & get_coroutine_context() LIBCOPP_MACRO_NOEXCEPT
coroutine_type coroutine_t
bool is_completed() const LIBCOPP_MACRO_NOEXCEPT override
LIBCOPP_COPP_NAMESPACE_ID::util::intrusive_ptr< self_type > ptr_type
static ptr_type create(Ty(TInst::*func), TInst *instance, size_t stack_size=0, size_t private_buffer_size=0)
ptr_type then(Ty &&functor, void *priv_data=nullptr)
create next task with functor using the same allocator and private buffer size as this task
void(* action_destroy_fn_)(void *)
static void * sub_buffer_offset(void *in, size_t off)
static LIBCOPP_COTASK_API_HEAD_ONLY ptr_type create_with_delegate(Ty &&callable, typename coroutine_type::allocator_type &alloc, size_t stack_size=0, size_t private_buffer_size=0)
create task with functor
TCO_MACRO macro_coroutine_type
ptr_type then(ptr_type next_task, void *priv_data=nullptr)
add task to run when task finished
static ptr_type create(Ty(*func)(void *), typename coroutine_type::allocator_type &alloc, size_t stack_size=0, size_t private_buffer_size=0)
create task with function
ptr_type next(Ty(TInst::*func), TInst *instance, typename coroutine_type::allocator_type &alloc, void *priv_data=nullptr, size_t stack_size=0, size_t private_buffer_size=0)
typename macro_coroutine_type::coroutine_type coroutine_type
task(const task &)=delete
int await_task(ptr_type wait_task)
await_task another cotask to finish
int start(void *priv_data, EN_TASK_STATUS expected_status=EN_TS_CREATED) override
coroutine_type::ptr_type coroutine_obj_
friend void intrusive_ptr_add_ref(self_type *p)
ptr_type next(Ty &&functor, void *priv_data=nullptr, size_t stack_size=0, size_t private_buffer_size=0)
create next task with functor
int cancel(void *priv_data) override
void * get_private_buffer()
typename macro_coroutine_type::stack_allocator_type stack_allocator_type
ptr_type next(Ty(*func)(void *), typename coroutine_type::allocator_type &alloc, void *priv_data=nullptr, size_t stack_size=0, size_t private_buffer_size=0)
int resume(void *priv_data, EN_TASK_STATUS expected_status=EN_TS_WAITING) override
static LIBCOPP_COTASK_API_HEAD_ONLY ptr_type create(Ty(TInst::*func), TInst *instance, typename coroutine_type::allocator_type &alloc, size_t stack_size=0, size_t private_buffer_size=0)
create task with function
#define LIBCOPP_MACRO_STD_COROUTINE_NAMESPACE
@ COPP_EC_SUCCESS
COPP_EC_SUCCESS.
@ COPP_EC_IS_RUNNING
COPP_EC_IS_RUNNING.
@ COPP_EC_TASK_NOT_IN_ACTION
COPP_EC_TASK_NOT_IN_ACTION.
@ COPP_EC_NOT_INITED
COPP_EC_NOT_INITED.
@ COPP_EC_TASK_ADD_NEXT_FAILED
COPP_EC_TASK_ADD_NEXT_FAILED.
@ COPP_EC_ALREADY_FINISHED
COPP_EC_ALREADY_FINISHED.
@ COPP_EC_TASK_IS_KILLED
COPP_EC_TASK_IS_KILLED.
@ COPP_EC_TASK_IS_EXITING
COPP_EC_TASK_IS_EXITING.
@ COPP_EC_TASK_CAN_NOT_WAIT_SELF
COPP_EC_TASK_CAN_NOT_WAIT_SELF.
@ COPP_EC_ARGS_ERROR
COPP_EC_ARGS_ERROR.
#define COPP_UNLIKELY_IF(...)
#define COPP_MACRO_STD_FORWARD(t, x)
#define COPP_LIKELY_IF(...)
LIBCOPP_COPP_API_HEAD_ONLY Tc * get()
get current coroutine and try to convert type
std::shared_ptr< cli::cmd_option_value > value_type
std::list< std::pair< ptr_type, void * > > member_list_
LIBCOPP_COTASK_API_HEAD_ONLY placement_destroy_fn_t get_placement_destroy(task_action_functor< Ty > *)
class LIBCOPP_COTASK_API_HEAD_ONLY task_manager