Skip to content

Commit

Permalink
C++20 coroutine support (#748)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr authored Sep 21, 2020
1 parent fa6bb7a commit ff7ab25
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 154 deletions.
16 changes: 8 additions & 8 deletions scratch/scratch.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..\..\..\library</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
Expand All @@ -151,7 +151,7 @@
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..\..\..\library</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
Expand All @@ -171,7 +171,7 @@
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..\..\..\library</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
Expand All @@ -191,7 +191,7 @@
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..\..\..\library</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
Expand All @@ -211,7 +211,7 @@
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..\..\..\library</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
Expand All @@ -233,7 +233,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..\..\..\library</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
Expand All @@ -257,7 +257,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..\..\..\library</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
Expand All @@ -281,7 +281,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..\..\..\library</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
Expand Down
22 changes: 13 additions & 9 deletions strings/base_coroutine_foundation.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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()
{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
{
}

Expand Down Expand Up @@ -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
{
}

Expand Down Expand Up @@ -355,7 +355,7 @@ namespace winrt::impl
if (remaining == 0)
{
std::atomic_thread_fence(std::memory_order_acquire);
std::experimental::coroutine_handle<Derived>::from_promise(*static_cast<Derived*>(this)).destroy();
coroutine_handle<Derived>::from_promise(*static_cast<Derived*>(this)).destroy();
}

return remaining;
Expand Down Expand Up @@ -496,7 +496,7 @@ namespace winrt::impl
}
}

std::experimental::suspend_never initial_suspend() const noexcept
suspend_never initial_suspend() const noexcept
{
return{};
}
Expand All @@ -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();
Expand Down Expand Up @@ -629,7 +629,11 @@ namespace winrt::impl
};
}

WINRT_EXPORT namespace std::experimental
#ifdef __cpp_lib_coroutine
namespace std
#else
namespace std::experimental
#endif
{
template <typename... Args>
struct coroutine_traits<winrt::Windows::Foundation::IAsyncAction, Args...>
Expand Down
2 changes: 1 addition & 1 deletion strings/base_coroutine_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -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]
{
Expand Down
2 changes: 1 addition & 1 deletion strings/base_coroutine_system_winui.h
Original file line number Diff line number Diff line change
Expand Up @@ -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]
{
Expand Down
42 changes: 23 additions & 19 deletions strings/base_coroutine_threadpool.h
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand Down Expand Up @@ -56,26 +56,26 @@ 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<IContextCallback> const& context, std::experimental::coroutine_handle<> handle)
inline void resume_apartment_sync(com_ptr<IContextCallback> const& context, coroutine_handle<> handle)
{
com_callback_args args{};
args.data = handle.address();

check_hresult(context->ContextCallback(resume_apartment_callback, &args, guid_of<ICallbackWithNoReentrancyToApplicationSTA>(), 5, nullptr));
}

inline void resume_apartment_on_threadpool(com_ptr<IContextCallback> const& context, std::experimental::coroutine_handle<> handle)
inline void resume_apartment_on_threadpool(com_ptr<IContextCallback> const& context, coroutine_handle<> handle)
{
struct threadpool_resume
{
threadpool_resume(com_ptr<IContextCallback> const& context, std::experimental::coroutine_handle<> handle) :
threadpool_resume(com_ptr<IContextCallback> const& context, coroutine_handle<> handle) :
m_context(context), m_handle(handle) { }
com_ptr<IContextCallback> m_context;
std::experimental::coroutine_handle<> m_handle;
coroutine_handle<> m_handle;
};
auto state = std::make_unique<threadpool_resume>(context, handle);
submit_threadpool_callback([](void*, void* p)
Expand All @@ -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<IContextCallback>(WINRT_IMPL_CoGetObjectContext)))
{
Expand Down Expand Up @@ -246,7 +246,7 @@ namespace winrt::impl
}

template <typename U>
auto await_suspend(std::experimental::coroutine_handle<U> handle)
auto await_suspend(coroutine_handle<U> handle)
{
return awaitable.await_suspend(handle);
}
Expand Down Expand Up @@ -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);
}
Expand All @@ -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;

Expand All @@ -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 };
Expand All @@ -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);
Expand Down Expand Up @@ -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)));
Expand Down Expand Up @@ -435,7 +435,7 @@ WINRT_EXPORT namespace winrt

handle_type<timer_traits> m_timer;
Windows::Foundation::TimeSpan m_duration;
std::experimental::coroutine_handle<> m_handle;
impl::coroutine_handle<> m_handle;
std::atomic<state> m_state{ state::idle };
};

Expand Down Expand Up @@ -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)));
Expand Down Expand Up @@ -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<state> m_state{ state::idle };
};

Expand Down Expand Up @@ -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))
{
Expand All @@ -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
Expand Down Expand Up @@ -628,7 +628,11 @@ WINRT_EXPORT namespace winrt
struct fire_and_forget {};
}

#ifdef __cpp_lib_coroutine
namespace std
#else
namespace std::experimental
#endif
{
template <typename... Args>
struct coroutine_traits<winrt::fire_and_forget, Args...>
Expand Down
2 changes: 1 addition & 1 deletion strings/base_coroutine_ui_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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]
{
Expand Down
4 changes: 2 additions & 2 deletions strings/base_deferral.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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()
{
Expand Down
Loading

0 comments on commit ff7ab25

Please sign in to comment.