File windows.h¶
File List > coroutine > windows.h
Go to the documentation of this file.
#pragma once
#ifndef COROUTINE_SYSTEM_WRAPPER_H
#define COROUTINE_SYSTEM_WRAPPER_H
#if __has_include(<Windows.h>)
#include <Windows.h>
#else
#error "expect Windows platform for this file"
#endif
#include <system_error>
#include <coroutine/return.h>
namespace coro {
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_GAMES)
class set_or_cancel final {
HANDLE hobject;
public:
explicit set_or_cancel(HANDLE target) noexcept(false);
~set_or_cancel() noexcept = default;
set_or_cancel(const set_or_cancel&) = delete;
set_or_cancel(set_or_cancel&&) = delete;
set_or_cancel& operator=(const set_or_cancel&) = delete;
set_or_cancel& operator=(set_or_cancel&&) = delete;
private:
void suspend(coroutine_handle<void>) noexcept(false);
public:
uint32_t unregister() noexcept;
constexpr bool await_ready() const noexcept {
return false;
}
void await_suspend(coroutine_handle<void> coro) noexcept(false) {
return suspend(coro);
}
uint32_t await_resume() noexcept {
return unregister();
}
};
#endif // WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_GAMES
class continue_on_thread_pool final {
static void __stdcall resume_on_thread_pool(PTP_CALLBACK_INSTANCE, PVOID,
PTP_WORK);
uint32_t create_and_submit_work(coroutine_handle<void>) noexcept;
public:
constexpr bool await_ready() const noexcept {
return false;
}
constexpr void await_resume() noexcept {
// nothing to do for this implementation
}
void await_suspend(coroutine_handle<void> coro) noexcept(false) {
if (const auto ec = create_and_submit_work(coro))
throw std::system_error{static_cast<int>(ec),
std::system_category(),
"CreateThreadpoolWork"};
}
};
class continue_on_apc final {
static void __stdcall resume_on_apc(ULONG_PTR);
uint32_t queue_user_apc(coroutine_handle<void>) noexcept;
public:
constexpr bool await_ready() const noexcept {
return false;
}
constexpr void await_resume() noexcept {
}
void await_suspend(coroutine_handle<void> coro) noexcept(false) {
if (const auto ec = queue_user_apc(coro))
throw std::system_error{static_cast<int>(ec),
std::system_category(), "QueueUserAPC"};
}
public:
explicit continue_on_apc(HANDLE hThread) noexcept : thread{hThread} {
}
private:
HANDLE thread;
};
} // namespace coro
#endif // COROUTINE_SYSTEM_WRAPPER_H