mirror of
https://gitee.com/an-tao/drogon.git
synced 2024-11-29 18:27:43 +08:00
Add async_run (#1047)
This commit is contained in:
parent
4a6f298661
commit
ac4a816a99
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user