Struct AsyncTask
Synopsis
#include <lib/inc/drogon/utils/coroutine.h>
struct AsyncTask
Description
Fires a coroutine and doesn't force waiting nor deallocates upon promise destructs
Mentioned in
- Coroutines / Launching coroutines with lambda capture from a function
- Testing Framework / Asynchronous testing
Structures
promise_type |
Methods
AsyncTask overload | ||
await_ready | ||
await_resume | ||
await_suspend | ||
operator= overload |
Source
Lines 395-492 in lib/inc/drogon/utils/coroutine.h.
struct AsyncTask
{
struct promise_type;
using handle_type = std::coroutine_handle<promise_type>;
AsyncTask() = default;
AsyncTask(handle_type h) : coro_(h)
{
}
AsyncTask(const AsyncTask &) = delete;
AsyncTask(AsyncTask &&other)
{
coro_ = other.coro_;
other.coro_ = nullptr;
}
AsyncTask &operator=(const AsyncTask &) = delete;
AsyncTask &operator=(AsyncTask &&other)
{
if (std::addressof(other) == this)
return *this;
coro_ = other.coro_;
other.coro_ = nullptr;
return *this;
}
struct promise_type
{
std::coroutine_handle<> continuation_;
AsyncTask get_return_object() noexcept
{
return {std::coroutine_handle<promise_type>::from_promise(*this)};
}
std::suspend_never initial_suspend() const noexcept
{
return {};
}
void unhandled_exception()
{
LOG_FATAL << "Exception escaping AsyncTask.";
std::terminate();
}
void return_void() noexcept
{
}
void setContinuation(std::coroutine_handle<> handle)
{
continuation_ = handle;
}
auto final_suspend() const noexcept
{
// Can't simply use suspend_never because we need symmetric transfer
struct awaiter final
{
bool await_ready() const noexcept
{
return true;
}
auto await_suspend(
std::coroutine_handle<promise_type> coro) const noexcept
{
return coro.promise().continuation_;
}
void await_resume() const noexcept
{
}
};
return awaiter{};
}
};
bool await_ready() const noexcept
{
return coro_.done();
}
void await_resume() const noexcept
{
}
auto await_suspend(std::coroutine_handle<> coroutine) noexcept
{
coro_.promise().setContinuation(coroutine);
return coro_;
}
handle_type coro_;
};