Skip to content

Commit

Permalink
Fix issue 18
Browse files Browse the repository at this point in the history
  • Loading branch information
owent committed Sep 4, 2020
1 parent e40d880 commit b9f7abb
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 90 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
HISTORY
----------------

### 1.3.2

1. [FIX] [#16](https://github.com/owt5008137/libcopp/issues/16) : document of ```LIBCOPP_DISABLE_ATOMIC_LOCK``` and ```LIBCOPP_DISABLE_THIS_MT``` .
2. [FIX] [#18](https://github.com/owt5008137/libcopp/issues/18) : ```'xx' is not a member of 'xxx {aka xxx}'``` .
3. [OPTIMIZE] ```cotask::task``` can capture all integer type of return value now.

### 1.3.1 (2020-07-06)

1. Fix compiler version checker for C++20 coroutine
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ project(libcopp C CXX ASM)

set(LIBCOPP_VERSION_MAJOR "1")
set(LIBCOPP_VERSION_MINOR "3")
set(LIBCOPP_VERSION_PATCH "1")
set(LIBCOPP_VERSION_PATCH "2")
set(LIBCOPP_VERSION "${LIBCOPP_VERSION_MAJOR}.${LIBCOPP_VERSION_MINOR}.${LIBCOPP_VERSION_PATCH}")

########################################################################
Expand Down
102 changes: 66 additions & 36 deletions include/libcotask/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
#include <list>
#include <stdint.h>

#include <libcopp/utils/config/libcopp_build_features.h>
#include <libcopp/future/std_coroutine_generator.h>
#include <libcopp/utils/config/libcopp_build_features.h>

#if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
#include <exception>
Expand Down Expand Up @@ -46,7 +46,7 @@ namespace cotask {
using coroutine_t = typename macro_coroutine_t::coroutine_t;
using stack_allocator_t = typename macro_coroutine_t::stack_allocator_t;

using id_t = typename impl::task_impl::id_t;
using id_t = typename impl::task_impl::id_t;
using id_allocator_t = typename impl::task_impl::id_allocator_t;


Expand All @@ -61,7 +61,7 @@ namespace cotask {
typedef typename macro_coroutine_t::coroutine_t coroutine_t;
typedef typename macro_coroutine_t::stack_allocator_t stack_allocator_t;

typedef typename impl::task_impl::id_t id_t;
typedef typename impl::task_impl::id_t id_t;
typedef typename impl::task_impl::id_allocator_t id_allocator_t;

private:
Expand All @@ -82,7 +82,8 @@ namespace cotask {
,
binding_manager_ptr_(UTIL_CONFIG_NULLPTR), binding_manager_fn_(UTIL_CONFIG_NULLPTR)
#endif
{ }
{
}


/**
Expand All @@ -101,7 +102,11 @@ namespace cotask {
static LIBCOPP_COTASK_API_HEAD_ONLY ptr_t create_with_delegate(const Ty &callable, typename coroutine_t::allocator_type &alloc,
size_t stack_size = 0, size_t private_buffer_size = 0) {
#endif
#if defined(UTIL_CONFIG_COMPILER_CXX_ALIAS_TEMPLATES) && UTIL_CONFIG_COMPILER_CXX_ALIAS_TEMPLATES
using a_t = TAct;
#else
typedef TAct a_t;
#endif

if (0 == stack_size) {
stack_size = copp::stack_traits::default_size();
Expand Down Expand Up @@ -134,12 +139,16 @@ namespace cotask {
ret->coroutine_obj_->set_flags(impl::task_impl::ext_coroutine_flag_t::EN_ECFT_COTASK);

// placement new action
a_t *action = new (action_addr) a_t(std::forward<Ty>(callable));
a_t *action = new (action_addr) a_t(COPP_MACRO_STD_FORWARD(Ty, callable));
if (UTIL_CONFIG_NULLPTR == action) {
return ret;
}

#if defined(UTIL_CONFIG_COMPILER_CXX_ALIAS_TEMPLATES) && UTIL_CONFIG_COMPILER_CXX_ALIAS_TEMPLATES
using a_t_fn_t = int (a_t::*)(void *);
#else
typedef int (a_t::*a_t_fn_t)(void *);
#endif
a_t_fn_t a_t_fn = &a_t::operator();

// redirect runner
Expand Down Expand Up @@ -175,7 +184,15 @@ namespace cotask {
template <typename Ty>
static inline ptr_t create(Ty &&functor, typename coroutine_t::allocator_type &alloc, size_t stack_size = 0,
size_t private_buffer_size = 0) {
typedef typename std::conditional<std::is_base_of<impl::task_action_impl, Ty>::value, Ty, task_action_functor<Ty> >::type a_t;
#if defined(UTIL_CONFIG_COMPILER_CXX_ALIAS_TEMPLATES) && UTIL_CONFIG_COMPILER_CXX_ALIAS_TEMPLATES
using decay_type = typename std::decay<Ty>::type;
using a_t = typename std::conditional<std::is_base_of<impl::task_action_impl, decay_type>::value, decay_type,
task_action_functor<decay_type> >::type;
#else
typedef typename std::decay<Ty>::type decay_type;
typedef typename std::conditional<std::is_base_of<impl::task_action_impl, decay_type>::value, decay_type,
task_action_functor<decay_type> >::type a_t;
#endif
return create_with_delegate<a_t>(std::forward<Ty>(functor), alloc, stack_size, private_buffer_size);
}
#else
Expand All @@ -188,8 +205,10 @@ namespace cotask {
template <typename Ty>
static LIBCOPP_COTASK_API_HEAD_ONLY ptr_t create(const Ty &functor, typename coroutine_t::allocator_type &alloc,
size_t stack_size = 0, size_t private_buffer_size = 0) {
typedef typename std::conditional<std::is_base_of<impl::task_action_impl, Ty>::value, Ty, task_action_functor<Ty> >::type a_t;
return create_with_delegate<a_t>(std::forward<Ty>(functor), alloc, stack_size, private_buffer_size);
typedef typename std::decay<Ty>::type decay_type;
typedef typename std::conditional<std::is_base_of<impl::task_action_impl, decay_type>::value, decay_type,
task_action_functor<decay_type> >::type a_t;
return create_with_delegate<a_t>(functor, alloc, stack_size, private_buffer_size);
}
#endif

Expand All @@ -202,7 +221,11 @@ namespace cotask {
template <typename Ty>
static inline ptr_t create(Ty (*func)(void *), typename coroutine_t::allocator_type &alloc, size_t stack_size = 0,
size_t private_buffer_size = 0) {
typedef task_action_function<Ty> a_t;
#if defined(UTIL_CONFIG_COMPILER_CXX_ALIAS_TEMPLATES) && UTIL_CONFIG_COMPILER_CXX_ALIAS_TEMPLATES
using a_t = task_action_function<Ty>;
#else
typedef task_action_function<Ty> a_t;
#endif

return create_with_delegate<a_t>(func, alloc, stack_size, private_buffer_size);
}
Expand All @@ -222,7 +245,11 @@ namespace cotask {
template <typename Ty, typename TInst>
static LIBCOPP_COTASK_API_HEAD_ONLY ptr_t create(Ty(TInst::*func), TInst *instance, typename coroutine_t::allocator_type &alloc,
size_t stack_size = 0, size_t private_buffer_size = 0) {
#if defined(UTIL_CONFIG_COMPILER_CXX_ALIAS_TEMPLATES) && UTIL_CONFIG_COMPILER_CXX_ALIAS_TEMPLATES
using a_t = task_action_mem_function<Ty, TInst>;
#else
typedef task_action_mem_function<Ty, TInst> a_t;
#endif

return create<a_t>(a_t(func, instance), alloc, stack_size, private_buffer_size);
}
Expand All @@ -243,9 +270,13 @@ namespace cotask {
template <typename Ty, typename... TParams>
static LIBCOPP_COTASK_API_HEAD_ONLY ptr_t create_with(typename coroutine_t::allocator_type &alloc, size_t stack_size,
size_t private_buffer_size, TParams &&... args) {
typedef Ty a_t;
#if defined(UTIL_CONFIG_COMPILER_CXX_ALIAS_TEMPLATES) && UTIL_CONFIG_COMPILER_CXX_ALIAS_TEMPLATES
using a_t = Ty;
#else
typedef Ty a_t;
#endif

return create(std::move(a_t(std::forward<TParams>(args)...)), alloc, stack_size, private_buffer_size);
return create(a_t(std::forward<TParams>(args)...), alloc, stack_size, private_buffer_size);
}
#endif

Expand Down Expand Up @@ -311,7 +342,7 @@ namespace cotask {
template <typename Ty>
inline ptr_t next(const Ty &functor, typename coroutine_t::allocator_type &alloc, void *priv_data = UTIL_CONFIG_NULLPTR,
size_t stack_size = 0, size_t private_buffer_size = 0) {
return next(create(std::forward<Ty>(functor), alloc, stack_size, private_buffer_size), priv_data);
return next(create(functor, alloc, stack_size, private_buffer_size), priv_data);
}
#endif

Expand Down Expand Up @@ -440,11 +471,10 @@ namespace cotask {
inline ptr_t then(const Ty &functor, typename coroutine_t::allocator_type &alloc, void *priv_data = UTIL_CONFIG_NULLPTR,
size_t stack_size = 0, size_t private_buffer_size = 0) {
if (!coroutine_obj_) {
return then(create(std::forward<Ty>(functor), stack_size_, get_private_buffer_size()), priv_data);
return then(create(functor, stack_size_, get_private_buffer_size()), priv_data);
}

return then(create(std::forward<Ty>(functor), coroutine_obj_->get_allocator(), stack_size_, get_private_buffer_size()),
priv_data);
return then(create(functor, coroutine_obj_->get_allocator(), stack_size_, get_private_buffer_size()), priv_data);
}
#endif

Expand Down Expand Up @@ -488,12 +518,13 @@ namespace cotask {
#if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
virtual int start(void *priv_data, EN_TASK_STATUS expected_status = EN_TS_CREATED) UTIL_CONFIG_OVERRIDE {
std::list<std::exception_ptr> eptrs;
int ret = start(eptrs, priv_data, expected_status);
int ret = start(eptrs, priv_data, expected_status);
maybe_rethrow(eptrs);
return ret;
}

virtual int start(std::list<std::exception_ptr>& unhandled, void *priv_data, EN_TASK_STATUS expected_status = EN_TS_CREATED) LIBCOPP_MACRO_NOEXCEPT {
virtual int start(std::list<std::exception_ptr> &unhandled, void *priv_data,
EN_TASK_STATUS expected_status = EN_TS_CREATED) LIBCOPP_MACRO_NOEXCEPT {
#else
virtual int start(void *priv_data, EN_TASK_STATUS expected_status = EN_TS_CREATED) UTIL_CONFIG_OVERRIDE {
#endif
Expand Down Expand Up @@ -522,7 +553,7 @@ namespace cotask {

#if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
std::exception_ptr eptr;
int ret = coroutine_obj_->start(eptr, priv_data);
int ret = coroutine_obj_->start(eptr, priv_data);
if (eptr) {
unhandled.emplace_back(std::move(eptr));
}
Expand Down Expand Up @@ -571,7 +602,8 @@ namespace cotask {
return start(priv_data, expected_status);
}

virtual int resume(std::list<std::exception_ptr>& unhandled, void *priv_data, EN_TASK_STATUS expected_status = EN_TS_WAITING) LIBCOPP_MACRO_NOEXCEPT {
virtual int resume(std::list<std::exception_ptr> &unhandled, void *priv_data,
EN_TASK_STATUS expected_status = EN_TS_WAITING) LIBCOPP_MACRO_NOEXCEPT {
return start(unhandled, priv_data, expected_status);
}
#else
Expand All @@ -592,16 +624,16 @@ namespace cotask {
#if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
virtual int cancel(void *priv_data) UTIL_CONFIG_OVERRIDE {
std::list<std::exception_ptr> eptrs;
int ret = cancel(eptrs, priv_data);
int ret = cancel(eptrs, priv_data);
maybe_rethrow(eptrs);
return ret;
}

virtual int cancel(std::list<std::exception_ptr>& unhandled, void *priv_data) LIBCOPP_MACRO_NOEXCEPT {
virtual int cancel(std::list<std::exception_ptr> &unhandled, void *priv_data) LIBCOPP_MACRO_NOEXCEPT {
#else
virtual int cancel(void *priv_data) UTIL_CONFIG_OVERRIDE {
#endif

EN_TASK_STATUS from_status = get_status();

do {
Expand All @@ -625,12 +657,12 @@ namespace cotask {
#if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
virtual int kill(enum EN_TASK_STATUS status, void *priv_data) UTIL_CONFIG_OVERRIDE {
std::list<std::exception_ptr> eptrs;
int ret = kill(eptrs, status, priv_data);
int ret = kill(eptrs, status, priv_data);
maybe_rethrow(eptrs);
return ret;
}

virtual int kill(std::list<std::exception_ptr>& unhandled, enum EN_TASK_STATUS status, void *priv_data) LIBCOPP_MACRO_NOEXCEPT {
virtual int kill(std::list<std::exception_ptr> &unhandled, enum EN_TASK_STATUS status, void *priv_data) LIBCOPP_MACRO_NOEXCEPT {
#else
virtual int kill(enum EN_TASK_STATUS status, void *priv_data) UTIL_CONFIG_OVERRIDE {
#endif
Expand Down Expand Up @@ -671,9 +703,7 @@ namespace cotask {
}

#if defined(LIBCOPP_MACRO_ENABLE_WIN_FIBER) && LIBCOPP_MACRO_ENABLE_WIN_FIBER
virtual bool is_fiber() const LIBCOPP_MACRO_NOEXCEPT {
return std::is_base_of<copp::coroutine_context_fiber, coroutine_t>::value;
}
virtual bool is_fiber() const LIBCOPP_MACRO_NOEXCEPT { return std::is_base_of<copp::coroutine_context_fiber, coroutine_t>::value; }
#endif

static inline void *add_buffer_offset(void *in, size_t off) {
Expand Down Expand Up @@ -704,8 +734,8 @@ namespace cotask {
inline size_t use_count() const { return ref_count_.load(); }

#if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
static UTIL_FORCEINLINE void maybe_rethrow(std::list<std::exception_ptr>& eptrs) {
for (std::list<std::exception_ptr>::iterator iter = eptrs.begin(); iter != eptrs.end(); ++ iter) {
static UTIL_FORCEINLINE void maybe_rethrow(std::list<std::exception_ptr> &eptrs) {
for (std::list<std::exception_ptr>::iterator iter = eptrs.begin(); iter != eptrs.end(); ++iter) {
coroutine_t::maybe_rethrow(*iter);
}
}
Expand All @@ -714,7 +744,7 @@ namespace cotask {
task(const task &) UTIL_CONFIG_DELETED_FUNCTION;

#if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
void active_next_tasks(std::list<std::exception_ptr>& unhandled) LIBCOPP_MACRO_NOEXCEPT {
void active_next_tasks(std::list<std::exception_ptr> &unhandled) LIBCOPP_MACRO_NOEXCEPT {
#else
void active_next_tasks() {
#endif
Expand Down Expand Up @@ -761,12 +791,12 @@ namespace cotask {
#if defined(LIBCOPP_MACRO_ENABLE_STD_COROUTINE) && LIBCOPP_MACRO_ENABLE_STD_COROUTINE
// and then, resume all std coroutine handles
while (!next_std_handles_.empty()) {
if(!*next_std_handles_.begin()) {
if (!*next_std_handles_.begin()) {
next_std_handles_.pop_front();
continue;
}

if((*next_std_handles_.begin()).done()) {
if ((*next_std_handles_.begin()).done()) {
next_std_handles_.pop_front();
continue;
}
Expand All @@ -784,7 +814,7 @@ namespace cotask {
}

#if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
int _notify_finished(std::list<std::exception_ptr>& unhandled, void *priv_data) LIBCOPP_MACRO_NOEXCEPT {
int _notify_finished(std::list<std::exception_ptr> &unhandled, void *priv_data) LIBCOPP_MACRO_NOEXCEPT {
#else
int _notify_finished(void *priv_data) {
#endif
Expand Down Expand Up @@ -931,7 +961,7 @@ namespace cotask {
}

protected:
ptr_t refer_task_;
ptr_t refer_task_;
typename std::list<LIBCOPP_MACRO_FUTURE_COROUTINE_VOID>::iterator await_handle_iter_;
};

Expand Down Expand Up @@ -966,8 +996,8 @@ namespace cotask {
#if defined(LIBCOPP_MACRO_ENABLE_STD_COROUTINE) && LIBCOPP_MACRO_ENABLE_STD_COROUTINE
template <typename TCO_MACRO>
auto operator co_await(libcopp::util::intrusive_ptr<task<TCO_MACRO> > t) LIBCOPP_MACRO_NOEXCEPT {
typedef typename task<TCO_MACRO>::awaitable_base_t awaitable_t;
return awaitable_t{t};
using awaitable_t = typename task<TCO_MACRO>::awaitable_base_t;
return awaitable_t{t};
}
#endif
} // namespace cotask
Expand Down
Loading

0 comments on commit b9f7abb

Please sign in to comment.