@@ -71,9 +71,36 @@ RESUMEF_NS | |||
{ | |||
} | |||
template<class _Ty, class _Ptr> | |||
static auto try_pop_list(intrusive_link_queue<_Ty, _Ptr>& list) | |||
{ | |||
return list.try_pop(); | |||
} | |||
template<class _Ptr> | |||
static _Ptr try_pop_list(std::list<_Ptr>& list) | |||
{ | |||
if (!list.empty()) | |||
{ | |||
_Ptr ptr = list.front(); | |||
list.pop_front(); | |||
return ptr; | |||
} | |||
return nullptr; | |||
} | |||
template<class _Ty, class _Ptr> | |||
static void clear_list(intrusive_link_queue<_Ty, _Ptr>& list) | |||
{ | |||
for (; list.try_pop() != nullptr;); | |||
} | |||
template<class _Ptr> | |||
static void clear_list(std::list<_Ptr>& list) | |||
{ | |||
list.clear(); | |||
} | |||
event_v2_impl::~event_v2_impl() | |||
{ | |||
for (; _wait_awakes.try_pop() != nullptr;); | |||
clear_list(_wait_awakes); | |||
} | |||
void event_v2_impl::signal_all() noexcept | |||
@@ -83,7 +110,7 @@ RESUMEF_NS | |||
_counter.store(0, std::memory_order_release); | |||
counted_ptr<state_event_t> state; | |||
for (; (state = _wait_awakes.try_pop()) != nullptr;) | |||
for (; (state = try_pop_list(_wait_awakes)) != nullptr;) | |||
{ | |||
(void)state->on_notify(); | |||
} | |||
@@ -94,7 +121,7 @@ RESUMEF_NS | |||
scoped_lock<lock_type> lock_(_lock); | |||
counted_ptr<state_event_t> state; | |||
for (; (state = _wait_awakes.try_pop()) != nullptr;) | |||
for (; (state = try_pop_list(_wait_awakes)) != nullptr;) | |||
{ | |||
if (state->on_notify()) | |||
return; |
@@ -24,9 +24,12 @@ RESUMEF_NS | |||
public: | |||
static constexpr bool USE_SPINLOCK = true; | |||
static constexpr bool USE_LINK_QUEUE = false; | |||
using lock_type = std::conditional_t<USE_SPINLOCK, spinlock, std::deque<std::recursive_mutex>>; | |||
using wait_queue_type = intrusive_link_queue<state_event_t, counted_ptr<state_event_t>>; | |||
using lock_type = std::conditional_t<USE_SPINLOCK, spinlock, std::recursive_mutex>; | |||
using state_event_ptr = counted_ptr<state_event_t>; | |||
using link_state_queue = intrusive_link_queue<state_event_t, state_event_ptr>; | |||
using wait_queue_type = std::conditional_t<USE_LINK_QUEUE, link_state_queue, std::list<state_event_ptr>>; | |||
friend struct state_event_t; | |||
@@ -159,7 +159,7 @@ RESUMEF_NS | |||
{ | |||
return operator co_await(static_cast<T&&>(value)); | |||
} | |||
template<class T, std::enable_if_t<is_awaitor_v<T&&>, int> = 0> | |||
template<class T, std::enable_if_t<is_awaitor_v<T>, int> = 0> | |||
T&& get_awaitor_impl(T&& value, std::any) noexcept | |||
{ | |||
return static_cast<T&&>(value); |
@@ -101,14 +101,20 @@ RESUMEF_NS | |||
}; | |||
template<class _Ty, bool = traits::is_callable_v<_Ty>> | |||
struct awaitor_result_impl | |||
struct awaitor_result_impl2 | |||
{ | |||
using value_type = typename convert_void_2_ignore< | |||
typename traits::awaitor_traits<_Ty>::value_type | |||
>::value_type; | |||
}; | |||
template<class _Ty> | |||
struct awaitor_result_impl<_Ty, true> : awaitor_result_impl<decltype(std::declval<_Ty>()()), false> {}; | |||
struct awaitor_result_impl2<_Ty, true> : awaitor_result_impl2<decltype(std::declval<_Ty>()()), false> {}; | |||
template<class... _Ty> | |||
struct awaitor_result_impl{}; | |||
template<class _Ty> | |||
struct awaitor_result_impl<_Ty> : public awaitor_result_impl2<_Ty> {}; | |||
template<_WhenTaskT _Ty> | |||
using awaitor_result_t = typename awaitor_result_impl<std::remove_reference_t<_Ty>>::value_type; | |||
@@ -40,7 +40,7 @@ | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | |||
<ConfigurationType>Application</ConfigurationType> | |||
<PlatformToolset>v142</PlatformToolset> | |||
<PlatformToolset>ClangCL</PlatformToolset> | |||
<UseDebugLibraries>true</UseDebugLibraries> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> |