[+] AuVoidTask
(https://devblogs.microsoft.com/oldnewthing/20190116-00/?p=100715) [*] Amend coroutines Awaitable to prevent use after free
This commit is contained in:
parent
69a5bb8061
commit
a1b07c634a
@ -693,6 +693,69 @@ namespace std
|
||||
#endif
|
||||
}
|
||||
|
||||
struct AuVoidTask
|
||||
{
|
||||
struct promise_type
|
||||
{
|
||||
AuVoidTask get_return_object()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::suspend_never initial_suspend()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::suspend_never final_suspend() noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
void return_void()
|
||||
{ }
|
||||
|
||||
void unhandled_exception()
|
||||
{ }
|
||||
};
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
#include <pplawait.h>
|
||||
|
||||
using AuVoidTask = concurrency::task<void>;
|
||||
#else
|
||||
struct AuVoidTask
|
||||
{
|
||||
struct promise_type
|
||||
{
|
||||
AuVoidTask get_return_object()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
bool initial_suspend()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool final_suspend() noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void return_void()
|
||||
{ }
|
||||
|
||||
void unhandled_exception()
|
||||
{ }
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace __detail
|
||||
@ -702,6 +765,11 @@ namespace __detail
|
||||
{
|
||||
AuSharedFuture<A, B> pFuture;
|
||||
|
||||
Awaitable(AuSharedFuture<A, B> pFuture) :
|
||||
pFuture(pFuture)
|
||||
{
|
||||
}
|
||||
|
||||
bool await_ready()
|
||||
{
|
||||
return __detail::FutureAccessor::IsFinished(*pFuture.get());
|
||||
@ -710,21 +778,28 @@ namespace __detail
|
||||
template <typename T>
|
||||
void await_suspend(T h)
|
||||
{
|
||||
pFuture->OnComplete([=](const A &)
|
||||
auto pFuture = this->pFuture;
|
||||
|
||||
pFuture->OnComplete([h = h](const A &)
|
||||
{
|
||||
h.resume();
|
||||
});
|
||||
|
||||
if (__detail::FutureAccessor::IsFinished(*pFuture.get()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if constexpr (!AuIsVoid_v<B>)
|
||||
{
|
||||
pFuture->OnFailure([=](const B &)
|
||||
pFuture->OnFailure([h = h](const B &)
|
||||
{
|
||||
h.resume();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
pFuture->OnFailure([=]()
|
||||
pFuture->OnFailure([h = h]()
|
||||
{
|
||||
h.resume();
|
||||
});
|
||||
@ -757,21 +832,28 @@ namespace __detail
|
||||
template <typename T>
|
||||
void await_suspend(T h)
|
||||
{
|
||||
pFuture->OnComplete([=]()
|
||||
auto pFuture = this->pFuture;
|
||||
|
||||
pFuture->OnComplete([h = h]()
|
||||
{
|
||||
h.resume();
|
||||
});
|
||||
|
||||
if (__detail::FutureAccessor::IsFinished(*pFuture.get()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if constexpr (!AuIsVoid_v<B>)
|
||||
{
|
||||
pFuture->OnFailure([=](const B &)
|
||||
pFuture->OnFailure([h = h](const B &)
|
||||
{
|
||||
h.resume();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
pFuture->OnFailure([=]()
|
||||
pFuture->OnFailure([h = h]()
|
||||
{
|
||||
h.resume();
|
||||
});
|
||||
@ -788,14 +870,14 @@ namespace __detail
|
||||
#if defined(__AUHAS_COROUTINES_CO_AWAIT)
|
||||
|
||||
template <typename A, typename B, AU_TEMPLATE_ENABLE_WHEN(!AuIsVoid_v<A>)>
|
||||
inline auto operator co_await (const AuSharedFuture<A, B> &pFuture)
|
||||
inline auto operator co_await (AuSharedFuture<A, B> pFuture)
|
||||
{
|
||||
SysAssert(pFuture);
|
||||
return __detail::Awaitable<A, B> { pFuture };
|
||||
}
|
||||
|
||||
template <typename A, typename B, AU_TEMPLATE_ENABLE_WHEN(AuIsVoid_v<A>)>
|
||||
inline auto operator co_await (const AuSharedFuture<A, B> &pFuture)
|
||||
inline auto operator co_await (AuSharedFuture<A, B> pFuture)
|
||||
{
|
||||
SysAssert(pFuture);
|
||||
return __detail::AwaitableVoid<B> { pFuture };
|
||||
|
Loading…
Reference in New Issue
Block a user