From a8f0b7ef06ae6c26333b2517df23c1a262faa897 Mon Sep 17 00:00:00 2001 From: Kenny Kerr Date: Mon, 21 Sep 2020 09:59:42 -0700 Subject: [PATCH] coro20 --- scratch/scratch.vcxproj | 16 ++-- strings/base_coroutine_foundation.h | 22 +++-- strings/base_coroutine_system.h | 2 +- strings/base_coroutine_system_winui.h | 2 +- strings/base_coroutine_threadpool.h | 42 +++++---- strings/base_coroutine_ui_core.h | 2 +- strings/base_deferral.h | 4 +- strings/base_includes.h | 129 ++++---------------------- 8 files changed, 65 insertions(+), 154 deletions(-) diff --git a/scratch/scratch.vcxproj b/scratch/scratch.vcxproj index df71cbdac..237ca4eeb 100644 --- a/scratch/scratch.vcxproj +++ b/scratch/scratch.vcxproj @@ -129,7 +129,7 @@ true $(OutputPath);Generated Files;..\..\..\library NOMINMAX;_MBCS;%(PreprocessorDefinitions) - /await %(AdditionalOptions) + %(AdditionalOptions) MultiThreaded @@ -151,7 +151,7 @@ Disabled $(OutputPath);Generated Files;..\..\..\library _MBCS;%(PreprocessorDefinitions) - /await %(AdditionalOptions) + %(AdditionalOptions) MultiThreadedDebug @@ -171,7 +171,7 @@ Disabled $(OutputPath);Generated Files;..\..\..\library _MBCS;%(PreprocessorDefinitions) - /await %(AdditionalOptions) + %(AdditionalOptions) MultiThreadedDebug @@ -191,7 +191,7 @@ Disabled $(OutputPath);Generated Files;..\..\..\library _MBCS;%(PreprocessorDefinitions) - /await %(AdditionalOptions) + %(AdditionalOptions) MultiThreadedDebug @@ -211,7 +211,7 @@ Disabled $(OutputPath);Generated Files;..\..\..\library _MBCS;%(PreprocessorDefinitions) - /await %(AdditionalOptions) + %(AdditionalOptions) MultiThreadedDebug @@ -233,7 +233,7 @@ true $(OutputPath);Generated Files;..\..\..\library NOMINMAX;_MBCS;%(PreprocessorDefinitions) - /await %(AdditionalOptions) + %(AdditionalOptions) MultiThreaded @@ -257,7 +257,7 @@ true $(OutputPath);Generated Files;..\..\..\library NOMINMAX;_MBCS;%(PreprocessorDefinitions) - /await %(AdditionalOptions) + %(AdditionalOptions) MultiThreaded @@ -281,7 +281,7 @@ true $(OutputPath);Generated Files;..\..\..\library NOMINMAX;_MBCS;%(PreprocessorDefinitions) - /await %(AdditionalOptions) + %(AdditionalOptions) MultiThreaded diff --git a/strings/base_coroutine_foundation.h b/strings/base_coroutine_foundation.h index 666268015..5ebe8c617 100644 --- a/strings/base_coroutine_foundation.h +++ b/strings/base_coroutine_foundation.h @@ -100,7 +100,7 @@ namespace winrt::impl struct disconnect_aware_handler { - disconnect_aware_handler(std::experimental::coroutine_handle<> handle) noexcept + disconnect_aware_handler(coroutine_handle<> handle) noexcept : m_handle(handle) { } disconnect_aware_handler(disconnect_aware_handler&& other) noexcept @@ -119,7 +119,7 @@ namespace winrt::impl private: resume_apartment_context m_context; - std::experimental::coroutine_handle<> m_handle; + coroutine_handle<> m_handle; void Complete() { @@ -148,7 +148,7 @@ namespace winrt::impl return false; } - void await_suspend(std::experimental::coroutine_handle<> handle) + void await_suspend(coroutine_handle<> handle) { auto extend_lifetime = async; async.Completed([this, handler = disconnect_aware_handler{ handle }](auto&&, auto operation_status) mutable @@ -282,7 +282,7 @@ namespace winrt::impl return true; } - void await_suspend(std::experimental::coroutine_handle<>) const noexcept + void await_suspend(coroutine_handle<>) const noexcept { } @@ -324,7 +324,7 @@ namespace winrt::impl return true; } - void await_suspend(std::experimental::coroutine_handle<>) const noexcept + void await_suspend(coroutine_handle<>) const noexcept { } @@ -355,7 +355,7 @@ namespace winrt::impl if (remaining == 0) { std::atomic_thread_fence(std::memory_order_acquire); - std::experimental::coroutine_handle::from_promise(*static_cast(this)).destroy(); + coroutine_handle::from_promise(*static_cast(this)).destroy(); } return remaining; @@ -496,7 +496,7 @@ namespace winrt::impl } } - std::experimental::suspend_never initial_suspend() const noexcept + suspend_never initial_suspend() const noexcept { return{}; } @@ -514,7 +514,7 @@ namespace winrt::impl { } - bool await_suspend(std::experimental::coroutine_handle<>) const noexcept + bool await_suspend(coroutine_handle<>) const noexcept { promise->set_completed(); uint32_t const remaining = promise->subtract_reference(); @@ -629,7 +629,11 @@ namespace winrt::impl }; } -WINRT_EXPORT namespace std::experimental +#ifdef __cpp_lib_coroutine +namespace std +#else +namespace std::experimental +#endif { template struct coroutine_traits diff --git a/strings/base_coroutine_system.h b/strings/base_coroutine_system.h index 92a83feaa..3d97437cf 100644 --- a/strings/base_coroutine_system.h +++ b/strings/base_coroutine_system.h @@ -23,7 +23,7 @@ WINRT_EXPORT namespace winrt return m_queued; } - bool await_suspend(std::experimental::coroutine_handle<> handle) + bool await_suspend(impl::coroutine_handle<> handle) { return m_dispatcher.TryEnqueue(m_priority, [handle, this] { diff --git a/strings/base_coroutine_system_winui.h b/strings/base_coroutine_system_winui.h index 770573664..f3d91407f 100644 --- a/strings/base_coroutine_system_winui.h +++ b/strings/base_coroutine_system_winui.h @@ -23,7 +23,7 @@ WINRT_EXPORT namespace winrt return m_queued; } - bool await_suspend(std::experimental::coroutine_handle<> handle) + bool await_suspend(impl::coroutine_handle<> handle) { return m_dispatcher.TryEnqueue(m_priority, [handle, this] { diff --git a/strings/base_coroutine_threadpool.h b/strings/base_coroutine_threadpool.h index b630ef5c8..5ee881c34 100644 --- a/strings/base_coroutine_threadpool.h +++ b/strings/base_coroutine_threadpool.h @@ -11,10 +11,10 @@ namespace winrt::impl inline void __stdcall resume_background_callback(void*, void* context) noexcept { - std::experimental::coroutine_handle<>::from_address(context)(); + coroutine_handle<>::from_address(context)(); }; - inline auto resume_background(std::experimental::coroutine_handle<> handle) + inline auto resume_background(coroutine_handle<> handle) { submit_threadpool_callback(resume_background_callback, handle.address()); } @@ -56,11 +56,11 @@ namespace winrt::impl inline int32_t __stdcall resume_apartment_callback(com_callback_args* args) noexcept { - std::experimental::coroutine_handle<>::from_address(args->data)(); + coroutine_handle<>::from_address(args->data)(); return 0; }; - inline void resume_apartment_sync(com_ptr const& context, std::experimental::coroutine_handle<> handle) + inline void resume_apartment_sync(com_ptr const& context, coroutine_handle<> handle) { com_callback_args args{}; args.data = handle.address(); @@ -68,14 +68,14 @@ namespace winrt::impl check_hresult(context->ContextCallback(resume_apartment_callback, &args, guid_of(), 5, nullptr)); } - inline void resume_apartment_on_threadpool(com_ptr const& context, std::experimental::coroutine_handle<> handle) + inline void resume_apartment_on_threadpool(com_ptr const& context, coroutine_handle<> handle) { struct threadpool_resume { - threadpool_resume(com_ptr const& context, std::experimental::coroutine_handle<> handle) : + threadpool_resume(com_ptr const& context, coroutine_handle<> handle) : m_context(context), m_handle(handle) { } com_ptr m_context; - std::experimental::coroutine_handle<> m_handle; + coroutine_handle<> m_handle; }; auto state = std::make_unique(context, handle); submit_threadpool_callback([](void*, void* p) @@ -86,7 +86,7 @@ namespace winrt::impl state.release(); } - inline auto resume_apartment(resume_apartment_context const& context, std::experimental::coroutine_handle<> handle) + inline auto resume_apartment(resume_apartment_context const& context, coroutine_handle<> handle) { if ((context.m_context == nullptr) || (context.m_context == try_capture(WINRT_IMPL_CoGetObjectContext))) { @@ -246,7 +246,7 @@ namespace winrt::impl } template - auto await_suspend(std::experimental::coroutine_handle handle) + auto await_suspend(coroutine_handle handle) { return awaitable.await_suspend(handle); } @@ -278,7 +278,7 @@ WINRT_EXPORT namespace winrt { } - void await_suspend(std::experimental::coroutine_handle<> handle) const + void await_suspend(impl::coroutine_handle<> handle) const { impl::resume_background(handle); } @@ -305,7 +305,7 @@ WINRT_EXPORT namespace winrt { } - void await_suspend(std::experimental::coroutine_handle<> resume) + void await_suspend(impl::coroutine_handle<> resume) { m_resume = resume; @@ -325,7 +325,7 @@ WINRT_EXPORT namespace winrt } T const& m_context; - std::experimental::coroutine_handle<> m_resume{ nullptr }; + impl::coroutine_handle<> m_resume{ nullptr }; }; return awaitable{ context }; @@ -342,7 +342,7 @@ WINRT_EXPORT namespace winrt { } - void await_suspend(std::experimental::coroutine_handle<> handle) const + void await_suspend(impl::coroutine_handle<> handle) const { auto copy = context; // resuming may destruct *this, so use a copy impl::resume_apartment(copy, handle); @@ -377,7 +377,7 @@ WINRT_EXPORT namespace winrt return m_duration.count() <= 0; } - void await_suspend(std::experimental::coroutine_handle<> handle) + void await_suspend(impl::coroutine_handle<> handle) { m_handle = handle; m_timer.attach(check_pointer(WINRT_IMPL_CreateThreadpoolTimer(callback, this, nullptr))); @@ -435,7 +435,7 @@ WINRT_EXPORT namespace winrt handle_type m_timer; Windows::Foundation::TimeSpan m_duration; - std::experimental::coroutine_handle<> m_handle; + impl::coroutine_handle<> m_handle; std::atomic m_state{ state::idle }; }; @@ -475,7 +475,7 @@ WINRT_EXPORT namespace winrt return WINRT_IMPL_WaitForSingleObject(m_handle, 0) == 0; } - void await_suspend(std::experimental::coroutine_handle<> resume) + void await_suspend(impl::coroutine_handle<> resume) { m_resume = resume; m_wait.attach(check_pointer(WINRT_IMPL_CreateThreadpoolWait(callback, this, nullptr))); @@ -538,7 +538,7 @@ WINRT_EXPORT namespace winrt Windows::Foundation::TimeSpan m_timeout; void* m_handle; uint32_t m_result{}; - std::experimental::coroutine_handle<> m_resume{ nullptr }; + impl::coroutine_handle<> m_resume{ nullptr }; std::atomic m_state{ state::idle }; }; @@ -568,7 +568,7 @@ WINRT_EXPORT namespace winrt { } - void await_suspend(std::experimental::coroutine_handle<> handle) + void await_suspend(impl::coroutine_handle<> handle) { if (!WINRT_IMPL_TrySubmitThreadpoolCallback(callback, handle.address(), &m_environment)) { @@ -580,7 +580,7 @@ WINRT_EXPORT namespace winrt static void __stdcall callback(void*, void* context) noexcept { - std::experimental::coroutine_handle<>::from_address(context)(); + impl::coroutine_handle<>::from_address(context)(); } struct pool_traits @@ -628,7 +628,11 @@ WINRT_EXPORT namespace winrt struct fire_and_forget {}; } +#ifdef __cpp_lib_coroutine +namespace std +#else namespace std::experimental +#endif { template struct coroutine_traits diff --git a/strings/base_coroutine_ui_core.h b/strings/base_coroutine_ui_core.h index 55177b058..2d4e24f83 100644 --- a/strings/base_coroutine_ui_core.h +++ b/strings/base_coroutine_ui_core.h @@ -22,7 +22,7 @@ WINRT_EXPORT namespace winrt { } - void await_suspend(std::experimental::coroutine_handle<> handle) const + void await_suspend(impl::coroutine_handle<> handle) const { m_dispatcher.RunAsync(m_priority, [handle] { diff --git a/strings/base_deferral.h b/strings/base_deferral.h index 4717df6ba..e0d568f03 100644 --- a/strings/base_deferral.h +++ b/strings/base_deferral.h @@ -22,7 +22,7 @@ WINRT_EXPORT namespace winrt [[nodiscard]] Windows::Foundation::IAsyncAction wait_for_deferrals() { - struct awaitable : std::experimental::suspend_always + struct awaitable : impl::suspend_always { bool await_suspend(coroutine_handle handle) { @@ -37,7 +37,7 @@ WINRT_EXPORT namespace winrt private: - using coroutine_handle = std::experimental::coroutine_handle<>; + using coroutine_handle = impl::coroutine_handle<>; void one_deferral_completed() { diff --git a/strings/base_includes.h b/strings/base_includes.h index eb50d30a2..7354a304c 100644 --- a/strings/base_includes.h +++ b/strings/base_includes.h @@ -24,127 +24,30 @@ #include #endif -#ifndef __clang__ +#ifdef __cpp_lib_coroutine -#include - -#else +#include -namespace std::experimental +namespace winrt::impl { - template struct coroutine_traits - { - using promise_type = typename R::promise_type; - }; - - template struct coroutine_handle; - - template <> struct coroutine_handle - { - coroutine_handle(decltype(nullptr)) noexcept - { - } - - coroutine_handle() noexcept - { - } - - static coroutine_handle from_address(void* address) noexcept - { - coroutine_handle result; - result.ptr = address; - return result; - } - - coroutine_handle& operator=(decltype(nullptr)) noexcept - { - ptr = nullptr; - return *this; - } - - explicit operator bool() const noexcept - { - return ptr; - } - - void* address() const noexcept - { - return ptr; - } - - void operator()() const - { - resume(); - } + template + using coroutine_handle = std::coroutine_handle; - void resume() const - { - __builtin_coro_resume(ptr); - } - - void destroy() const - { - __builtin_coro_destroy(ptr); - } - - bool done() const - { - return __builtin_coro_done(ptr); - } - - protected: - void* ptr{}; - }; - - template struct coroutine_handle : coroutine_handle<> - { - using coroutine_handle<>::operator=; - - static coroutine_handle from_address(void* address) noexcept - { - coroutine_handle result; - result.ptr = address; - return result; - } - - Promise& promise() const - { - return *reinterpret_cast(__builtin_coro_promise(ptr, alignof(Promise), false)); - } - - static coroutine_handle from_promise(Promise& promise) - { - coroutine_handle result; - result.ptr = __builtin_coro_promise(&promise, alignof(Promise), true); - return result; - } - }; + using suspend_always = std::suspend_always; + using suspend_never = std::suspend_never; +} - template - bool operator==(coroutine_handle const& left, coroutine_handle const& right) noexcept - { - return left.address() == right.address(); - } +#else - template - bool operator!=(coroutine_handle const& left, coroutine_handle const& right) noexcept - { - return !(left == right); - } +#include - struct suspend_always - { - bool await_ready() noexcept { return false; } - void await_suspend(coroutine_handle<>) noexcept {} - void await_resume() noexcept {} - }; +namespace winrt::impl +{ + template + using coroutine_handle = std::experimental::coroutine_handle; - struct suspend_never - { - bool await_ready() noexcept { return true; } - void await_suspend(coroutine_handle<>) noexcept {} - void await_resume() noexcept {} - }; + using suspend_always = std::experimental::suspend_always; + using suspend_never = std::experimental::suspend_never; } #endif