Add async_run (#1047)

This commit is contained in:
Martin Chang 2021-10-03 16:31:52 +08:00 committed by GitHub
parent 4a6f298661
commit ac4a816a99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 1 deletions

View File

@ -705,4 +705,26 @@ struct is_resumable<AsyncTask, std::void_t<AsyncTask>> : std::true_type
template <typename T>
constexpr bool is_resumable_v = is_resumable<T>::value;
/**
* @brief Runs a coroutine from a regular function
* @param coro an resubmable object or a coroutine that takes no parameters
*/
template <typename Coro>
void async_run(Coro &&coro)
{
if constexpr (std::is_invocable_v<Coro>)
async_run(std::move(coro()));
else if constexpr (std::is_same_v<Coro, AsyncTask>)
{
// Do nothing. AsyncTask runs on it's own.
}
else
{
using Awaiter = decltype(std::declval<Coro>().operator co_await());
using ResultType = decltype(std::declval<Awaiter>().await_resume());
static_assert(std::is_same_v<ResultType, void>);
[coro = std::move(coro)]() -> AsyncTask { co_await coro; }();
}
}
} // namespace drogon

View File

@ -95,6 +95,37 @@ DROGON_TEST(CroutineBasics)
CHECK(*ptr == 123);
};
sync_wait(await_non_copyable());
// TEST launching coroutine via the async_run API
// async_run should run the coroutine wthout waiting for anything else
int testVar = 0;
async_run([&testVar]() -> AsyncTask {
testVar = 1;
co_return;
}());
CHECK(testVar == 1); // This only works because neither async_run nor the
// coroutine within awaits
testVar = 0;
async_run([&testVar]() -> AsyncTask {
testVar = 1;
co_return;
}); // invoke coroutines with no parameters
CHECK(testVar == 1);
testVar = 0;
async_run([&testVar]() -> Task<void> {
testVar = 1;
co_return;
}());
CHECK(testVar == 1);
testVar = 0;
async_run([&testVar]() -> Task<void> {
testVar = 1;
co_return;
});
CHECK(testVar == 1);
}
DROGON_TEST(CompilcatedCoroutineLifetime)
@ -138,4 +169,4 @@ DROGON_TEST(CoroutineDestruction)
};
sync_wait(destruct());
CHECK(internal::SomeStruct::beenDestructed == true);
}
}