I'm trying to provide co-routine support for non WinRT types that will asynchronously execute on the Windows thread pool.
cppcoro and libunifex both provide the equivalent coroutine task type task<T>. I imagine it would be a good idea to run these tasks on the windows thread pool, but maybe I'm just being silly and should just use one of the thread pools provided these libraries.
On the other hand, I was hoping to see how cppwinrt handles this but I cant penetrate definition of IAsyncOperation
template <typename TResult>
struct __declspec(empty_bases) IAsyncOperation :
winrt::Windows::Foundation::IInspectable,
impl::consume_t<winrt::Windows::Foundation::IAsyncOperation<TResult>>,
impl::require<winrt::Windows::Foundation::IAsyncOperation<TResult>, winrt::Windows::Foundation::IAsyncInfo>
{
static_assert(impl::has_category_v<TResult>, "TResult must be WinRT type.");
IAsyncOperation(std::nullptr_t = nullptr) noexcept {}
IAsyncOperation(void* ptr, take_ownership_from_abi_t) noexcept : winrt::Windows::Foundation::IInspectable(ptr, take_ownership_from_abi) {}
};
Kenny Kerr did a talk at cppcon 2016 on this so maybe ill try watching that and then try greping the source code/generated headers.
The most hardest part about learning to implement coroutines is disambiguating the difference between awaitable types and coroutine promise types.
For now, I only need to poll if the object returned by my coroutine is ready (rather than
co_awaitit), but I need to be able to await onwinrt::resume_on_signalin the coroutine. cppwinrt does the work implementing the awaitable type inwinrt::resume_on_signaland I need to do the work implementing the promise type returned by the coroutine I callwinrt::resume_on_signalin.The simplest possible type you could return from a coroutine might be
std::shared_ptr<std::optional<T>and specializing coroutine_traits allows you to do this:which you can use as
However, there are caveats. You will create a race condition if you also make this an awaitable type oldnewthing, although I don't beleive you even could make it awaitable because you need to be able call a continuation when the value is set. And it doesn't handle exceptions.