{ | { | ||||
} | } | ||||
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() | event_v2_impl::~event_v2_impl() | ||||
{ | { | ||||
for (; _wait_awakes.try_pop() != nullptr;); | |||||
clear_list(_wait_awakes); | |||||
} | } | ||||
void event_v2_impl::signal_all() noexcept | void event_v2_impl::signal_all() noexcept | ||||
_counter.store(0, std::memory_order_release); | _counter.store(0, std::memory_order_release); | ||||
counted_ptr<state_event_t> state; | 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(); | (void)state->on_notify(); | ||||
} | } | ||||
scoped_lock<lock_type> lock_(_lock); | scoped_lock<lock_type> lock_(_lock); | ||||
counted_ptr<state_event_t> state; | 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()) | if (state->on_notify()) | ||||
return; | return; |
public: | public: | ||||
static constexpr bool USE_SPINLOCK = true; | 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; | friend struct state_event_t; | ||||
{ | { | ||||
return operator co_await(static_cast<T&&>(value)); | 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 | T&& get_awaitor_impl(T&& value, std::any) noexcept | ||||
{ | { | ||||
return static_cast<T&&>(value); | return static_cast<T&&>(value); |
}; | }; | ||||
template<class _Ty, bool = traits::is_callable_v<_Ty>> | 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< | using value_type = typename convert_void_2_ignore< | ||||
typename traits::awaitor_traits<_Ty>::value_type | typename traits::awaitor_traits<_Ty>::value_type | ||||
>::value_type; | >::value_type; | ||||
}; | }; | ||||
template<class _Ty> | 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> | template<_WhenTaskT _Ty> | ||||
using awaitor_result_t = typename awaitor_result_impl<std::remove_reference_t<_Ty>>::value_type; | using awaitor_result_t = typename awaitor_result_impl<std::remove_reference_t<_Ty>>::value_type; | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | ||||
<ConfigurationType>Application</ConfigurationType> | <ConfigurationType>Application</ConfigurationType> | ||||
<PlatformToolset>v142</PlatformToolset> | |||||
<PlatformToolset>ClangCL</PlatformToolset> | |||||
<UseDebugLibraries>true</UseDebugLibraries> | <UseDebugLibraries>true</UseDebugLibraries> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> |