this->_coro = nullptr; | this->_coro = nullptr; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
void on_await_suspend(coroutine_handle<_PromiseT> handler) noexcept | void on_await_suspend(coroutine_handle<_PromiseT> handler) noexcept | ||||
{ | { | ||||
_PromiseT& promise = handler.promise(); | _PromiseT& promise = handler.promise(); | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend(coroutine_handle<_PromiseT> handler) | bool await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
scoped_lock<lock_type> lock_(_channel->_lock); | scoped_lock<lock_type> lock_(_channel->_lock); | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend(coroutine_handle<_PromiseT> handler) | bool await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
scoped_lock<lock_type> lock_(_channel->_lock); | scoped_lock<lock_type> lock_(_channel->_lock); |
{ | { | ||||
return false; | return false; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend(coroutine_handle<_PromiseT> handler) | bool await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
_PromiseT& promise = handler.promise(); | _PromiseT& promise = handler.promise(); | ||||
return false; | return false; | ||||
} | } | ||||
scheduler_t* await_resume() const noexcept | scheduler_t* await_resume() const noexcept | ||||
{ | { | ||||
return _scheduler; | return _scheduler; | ||||
{ | { | ||||
return false; | return false; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend(coroutine_handle<_PromiseT> handler) | bool await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
_PromiseT& promise = handler.promise(); | _PromiseT& promise = handler.promise(); | ||||
return false; | return false; | ||||
} | } | ||||
state_base_t* await_resume() const noexcept | state_base_t* await_resume() const noexcept | ||||
{ | { | ||||
return _state; | return _state; | ||||
{ | { | ||||
return false; | return false; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend(coroutine_handle<_PromiseT> handler) | bool await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
_PromiseT& promise = handler.promise(); | _PromiseT& promise = handler.promise(); | ||||
return false; | return false; | ||||
} | } | ||||
task_t* await_resume() const noexcept | task_t* await_resume() const noexcept | ||||
{ | { | ||||
return _task; | return _task; |
virtual bool on_notify(event_v2_impl* eptr) = 0; | virtual bool on_notify(event_v2_impl* eptr) = 0; | ||||
virtual bool on_timeout() = 0; | virtual bool on_timeout() = 0; | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
scheduler_t* on_await_suspend(coroutine_handle<_PromiseT> handler) noexcept | scheduler_t* on_await_suspend(coroutine_handle<_PromiseT> handler) noexcept | ||||
{ | { | ||||
_PromiseT& promise = handler.promise(); | _PromiseT& promise = handler.promise(); | ||||
LIBRF_API bool on_notify(event_v2_impl* eptr, intptr_t idx); | LIBRF_API bool on_notify(event_v2_impl* eptr, intptr_t idx); | ||||
LIBRF_API bool on_timeout(); | LIBRF_API bool on_timeout(); | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
scheduler_t* on_await_suspend(coroutine_handle<_PromiseT> handler) noexcept | scheduler_t* on_await_suspend(coroutine_handle<_PromiseT> handler) noexcept | ||||
{ | { | ||||
_PromiseT& promise = handler.promise(); | _PromiseT& promise = handler.promise(); | ||||
return _event->try_wait_one(); | return _event->try_wait_one(); | ||||
} | } | ||||
template<class _PromiseT, class _Timeout, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT, class _Timeout> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend2(coroutine_handle<_PromiseT> handler, const _Timeout& cb) | bool await_suspend2(coroutine_handle<_PromiseT> handler, const _Timeout& cb) | ||||
{ | { | ||||
(void)cb; | (void)cb; | ||||
return true; | return true; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend(coroutine_handle<_PromiseT> handler) | bool await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
return await_suspend2(handler, nullptr); | return await_suspend2(handler, nullptr); | ||||
: _Btype(std::forward<Args>(args)...) | : _Btype(std::forward<Args>(args)...) | ||||
, _tp(tp) | , _tp(tp) | ||||
{} | {} | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend(coroutine_handle<_PromiseT> handler) | bool await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
if (!_Btype::await_suspend2(handler, [this]{ this->_state->add_timeout_timer(_tp);})) | if (!_Btype::await_suspend2(handler, [this]{ this->_state->add_timeout_timer(_tp);})) | ||||
return _begin == _end; | return _begin == _end; | ||||
} | } | ||||
template<class _PromiseT, class _Timeout, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT, class _Timeout> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend2(coroutine_handle<_PromiseT> handler, const _Timeout& cb) | bool await_suspend2(coroutine_handle<_PromiseT> handler, const _Timeout& cb) | ||||
{ | { | ||||
(void)cb; | (void)cb; | ||||
return true; | return true; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend(coroutine_handle<_PromiseT> handler) | bool await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
return await_suspend2(handler, nullptr); | return await_suspend2(handler, nullptr); | ||||
return _value; | return _value; | ||||
} | } | ||||
template<class _PromiseT, class _Timeout, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT, class _Timeout> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend2(coroutine_handle<_PromiseT> handler, const _Timeout& cb) | bool await_suspend2(coroutine_handle<_PromiseT> handler, const _Timeout& cb) | ||||
{ | { | ||||
(void)cb; | (void)cb; | ||||
return true; | return true; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend(coroutine_handle<_PromiseT> handler) | bool await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
return await_suspend2(handler, nullptr); | return await_suspend2(handler, nullptr); |
* @param mtxs... 需要获得的锁列表。 | * @param mtxs... 需要获得的锁列表。 | ||||
* @return [co_await] batch_unlock_t | * @return [co_await] batch_unlock_t | ||||
*/ | */ | ||||
template<class... _Mtxs | |||||
#ifndef DOXYGEN_SKIP_PROPERTY | |||||
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>> | |||||
#endif //DOXYGEN_SKIP_PROPERTY | |||||
> | |||||
template<class... _Mtxs> requires(std::same_as<_Mtxs, mutex_t> && ...) | |||||
static future_t<batch_unlock_t<_Mtxs...>> lock(_Mtxs&... mtxs); | static future_t<batch_unlock_t<_Mtxs...>> lock(_Mtxs&... mtxs); | ||||
/** | /** | ||||
* @param mtxs... 需要获得的锁列表。 | * @param mtxs... 需要获得的锁列表。 | ||||
* @return [co_await] void | * @return [co_await] void | ||||
*/ | */ | ||||
template<class... _Mtxs | |||||
#ifndef DOXYGEN_SKIP_PROPERTY | |||||
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>> | |||||
#endif //DOXYGEN_SKIP_PROPERTY | |||||
> | |||||
template<class... _Mtxs> requires(std::same_as<_Mtxs, mutex_t> && ...) | |||||
static future_t<> lock(adopt_manual_unlock_t manual_unlock_tag, _Mtxs&... mtxs); | static future_t<> lock(adopt_manual_unlock_t manual_unlock_tag, _Mtxs&... mtxs); | ||||
/** | /** | ||||
* @param mtxs... 需要解锁的锁列表。 | * @param mtxs... 需要解锁的锁列表。 | ||||
* @return [co_await] void | * @return [co_await] void | ||||
*/ | */ | ||||
template<class... _Mtxs | |||||
#ifndef DOXYGEN_SKIP_PROPERTY | |||||
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>> | |||||
#endif //DOXYGEN_SKIP_PROPERTY | |||||
> | |||||
template<class... _Mtxs> requires(std::same_as<_Mtxs, mutex_t> && ...) | |||||
static future_t<> unlock(_Mtxs&... mtxs); | static future_t<> unlock(_Mtxs&... mtxs); | ||||
* @param mtxs... 需要获得的锁列表。 | * @param mtxs... 需要获得的锁列表。 | ||||
* @return batch_unlock_t | * @return batch_unlock_t | ||||
*/ | */ | ||||
template<class... _Mtxs | |||||
#ifndef DOXYGEN_SKIP_PROPERTY | |||||
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>> | |||||
#endif //DOXYGEN_SKIP_PROPERTY | |||||
> | |||||
template<class... _Mtxs> requires(std::same_as<_Mtxs, mutex_t> && ...) | |||||
static batch_unlock_t<_Mtxs...> lock(void* unique_address, _Mtxs&... mtxs); | static batch_unlock_t<_Mtxs...> lock(void* unique_address, _Mtxs&... mtxs); | ||||
/** | /** | ||||
* @param unique_address 代表获得锁的拥有者。 | * @param unique_address 代表获得锁的拥有者。 | ||||
* @param mtxs... 需要获得的锁列表。 | * @param mtxs... 需要获得的锁列表。 | ||||
*/ | */ | ||||
template<class... _Mtxs | |||||
#ifndef DOXYGEN_SKIP_PROPERTY | |||||
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>> | |||||
#endif //DOXYGEN_SKIP_PROPERTY | |||||
> | |||||
template<class... _Mtxs> requires(std::same_as<_Mtxs, mutex_t> && ...) | |||||
static void lock(adopt_manual_unlock_t manual_unlock_tag, void* unique_address, _Mtxs&... mtxs); | static void lock(adopt_manual_unlock_t manual_unlock_tag, void* unique_address, _Mtxs&... mtxs); | ||||
/** | /** | ||||
* @param unique_address 代表获得锁的拥有者。 | * @param unique_address 代表获得锁的拥有者。 | ||||
* @param mtxs... 需要解锁的锁列表。 | * @param mtxs... 需要解锁的锁列表。 | ||||
*/ | */ | ||||
template<class... _Mtxs | |||||
#ifndef DOXYGEN_SKIP_PROPERTY | |||||
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>> | |||||
#endif //DOXYGEN_SKIP_PROPERTY | |||||
> | |||||
template<class... _Mtxs> requires(std::same_as<_Mtxs, mutex_t> && ...) | |||||
static void unlock(void* unique_address, _Mtxs&... mtxs); | static void unlock(void* unique_address, _Mtxs&... mtxs); | ||||
LIBRF_API mutex_t(); | LIBRF_API mutex_t(); |
: batch_unlock_t(std::adopt_lock, sch, mtx._mutex) | : batch_unlock_t(std::adopt_lock, sch, mtx._mutex) | ||||
{} | {} | ||||
/* | |||||
//此函数,适合在非协程里使用 | |||||
batch_unlock_t(void* sch, mutex_impl_ptr mtx) | |||||
: _mutex(std::move(mtx)) | |||||
, _owner(sch) | |||||
{ | |||||
if (_mutex != nullptr) | |||||
_mutex->lock_until_succeed(sch); | |||||
} | |||||
batch_unlock_t(void* sch, const mutex_t& mtx) | |||||
: batch_unlock_t(sch, mtx._mutex) | |||||
{} | |||||
*/ | |||||
/* | |||||
//此函数,适合在非协程里使用 | |||||
batch_unlock_t(void* sch, mutex_impl_ptr mtx) | |||||
: _mutex(std::move(mtx)) | |||||
, _owner(sch) | |||||
{ | |||||
if (_mutex != nullptr) | |||||
_mutex->lock_until_succeed(sch); | |||||
} | |||||
batch_unlock_t(void* sch, const mutex_t& mtx) | |||||
: batch_unlock_t(sch, mtx._mutex) | |||||
{} | |||||
*/ | |||||
~batch_unlock_t() | ~batch_unlock_t() | ||||
{ | { | ||||
return false; | return false; | ||||
} | } | ||||
template<class _PromiseT, class _Timeout, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT, class _Timeout> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend2(coroutine_handle<_PromiseT> handler, const _Timeout& cb) | bool await_suspend2(coroutine_handle<_PromiseT> handler, const _Timeout& cb) | ||||
{ | { | ||||
(void)cb; | (void)cb; | ||||
{ | { | ||||
using lock_awaiter::lock_awaiter; | using lock_awaiter::lock_awaiter; | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend(coroutine_handle<_PromiseT> handler) | bool await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
return await_suspend2(handler, nullptr); | return await_suspend2(handler, nullptr); | ||||
struct mutex_t::manual_awaiter : public lock_awaiter | struct mutex_t::manual_awaiter : public lock_awaiter | ||||
{ | { | ||||
using lock_awaiter::lock_awaiter; | using lock_awaiter::lock_awaiter; | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend(coroutine_handle<_PromiseT> handler) | bool await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
return await_suspend2(handler, nullptr); | return await_suspend2(handler, nullptr); | ||||
return false; | return false; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend(coroutine_handle<_PromiseT> handler) | bool await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
_PromiseT& promise = handler.promise(); | _PromiseT& promise = handler.promise(); | ||||
return false; | return false; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend(coroutine_handle<_PromiseT> handler) | bool await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
_PromiseT& promise = handler.promise(); | _PromiseT& promise = handler.promise(); | ||||
template<class... _Mtxs> | template<class... _Mtxs> | ||||
batch_unlock_t()->batch_unlock_t<_Mtxs...>; | batch_unlock_t()->batch_unlock_t<_Mtxs...>; | ||||
template<class... _Mtxs, typename> | |||||
template<class... _Mtxs> requires(std::same_as<_Mtxs, mutex_t> && ...) | |||||
inline future_t<batch_unlock_t<_Mtxs...>> mutex_t::lock(_Mtxs&... mtxs) | inline future_t<batch_unlock_t<_Mtxs...>> mutex_t::lock(_Mtxs&... mtxs) | ||||
{ | { | ||||
batch_unlock_t<_Mtxs...> unlock_guard{ std::adopt_lock, librf_root_state(), mtxs... }; | batch_unlock_t<_Mtxs...> unlock_guard{ std::adopt_lock, librf_root_state(), mtxs... }; | ||||
co_return std::move(unlock_guard); | co_return std::move(unlock_guard); | ||||
} | } | ||||
template<class... _Mtxs, typename> | |||||
template<class... _Mtxs> requires(std::same_as<_Mtxs, mutex_t> && ...) | |||||
inline future_t<> mutex_t::lock(adopt_manual_unlock_t _noused, _Mtxs&... mtxs) | inline future_t<> mutex_t::lock(adopt_manual_unlock_t _noused, _Mtxs&... mtxs) | ||||
{ | { | ||||
(void)_noused; //GCC: 这个参数不起一个名字,会导致GCC编译器内部错误。 | (void)_noused; //GCC: 这个参数不起一个名字,会导致GCC编译器内部错误。 | ||||
co_await detail::mutex_lock_await_lock_impl::_Lock_range(_MAA); | co_await detail::mutex_lock_await_lock_impl::_Lock_range(_MAA); | ||||
} | } | ||||
template<class... _Mtxs, typename> | |||||
template<class... _Mtxs> requires(std::same_as<_Mtxs, mutex_t> && ...) | |||||
inline future_t<> mutex_t::unlock(_Mtxs&... mtxs) | inline future_t<> mutex_t::unlock(_Mtxs&... mtxs) | ||||
{ | { | ||||
void* unique_address = librf_root_state(); | void* unique_address = librf_root_state(); | ||||
(mtxs.unlock(unique_address), ...); | (mtxs.unlock(unique_address), ...); | ||||
} | } | ||||
template<class... _Mtxs, typename> | |||||
template<class... _Mtxs> requires(std::same_as<_Mtxs, mutex_t> && ...) | |||||
inline batch_unlock_t<_Mtxs...> mutex_t::lock(void* unique_address, _Mtxs&... mtxs) | inline batch_unlock_t<_Mtxs...> mutex_t::lock(void* unique_address, _Mtxs&... mtxs) | ||||
{ | { | ||||
assert(unique_address != nullptr); | assert(unique_address != nullptr); | ||||
return su; | return su; | ||||
} | } | ||||
template<class... _Mtxs, typename> | |||||
template<class... _Mtxs> requires(std::same_as<_Mtxs, mutex_t> && ...) | |||||
inline void mutex_t::lock(adopt_manual_unlock_t, void* unique_address, _Mtxs&... mtxs) | inline void mutex_t::lock(adopt_manual_unlock_t, void* unique_address, _Mtxs&... mtxs) | ||||
{ | { | ||||
assert(unique_address != nullptr); | assert(unique_address != nullptr); | ||||
detail::scoped_lock_range_lock_impl::_Lock_range(_MAA); | detail::scoped_lock_range_lock_impl::_Lock_range(_MAA); | ||||
} | } | ||||
template<class... _Mtxs, typename> | |||||
template<class... _Mtxs> requires(std::same_as<_Mtxs, mutex_t> && ...) | |||||
inline void mutex_t::unlock(void* unique_address, _Mtxs&... mtxs) | inline void mutex_t::unlock(void* unique_address, _Mtxs&... mtxs) | ||||
{ | { | ||||
assert(unique_address != nullptr); | assert(unique_address != nullptr); |
{ | { | ||||
return false; | return false; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
inline void await_suspend(coroutine_handle<_PromiseT> handler) noexcept | inline void await_suspend(coroutine_handle<_PromiseT> handler) noexcept | ||||
{ | { | ||||
_PromiseT& promise = handler.promise(); | _PromiseT& promise = handler.promise(); | ||||
{ | { | ||||
return false; | return false; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
inline void await_suspend(coroutine_handle<_PromiseT> handler) noexcept | inline void await_suspend(coroutine_handle<_PromiseT> handler) noexcept | ||||
{ | { | ||||
_PromiseT& promise = handler.promise(); | _PromiseT& promise = handler.promise(); |
//scoped_lock<lock_type> __guard(this->_mtx); | //scoped_lock<lock_type> __guard(this->_mtx); | ||||
return _has_value.load(std::memory_order_acquire) != result_type::None; | return _has_value.load(std::memory_order_acquire) != result_type::None; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
void future_await_suspend(coroutine_handle<_PromiseT> handler); | void future_await_suspend(coroutine_handle<_PromiseT> handler); | ||||
LIBRF_API bool switch_scheduler_await_suspend(scheduler_t* sch); | LIBRF_API bool switch_scheduler_await_suspend(scheduler_t* sch); | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
void promise_initial_suspend(coroutine_handle<_PromiseT> handler); | void promise_initial_suspend(coroutine_handle<_PromiseT> handler); | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
void promise_final_suspend(coroutine_handle<_PromiseT> handler); | void promise_final_suspend(coroutine_handle<_PromiseT> handler); | ||||
#if RESUMEF_INLINE_STATE | #if RESUMEF_INLINE_STATE | ||||
} | } | ||||
auto future_await_resume() -> value_type; | auto future_await_resume() -> value_type; | ||||
template<class _PromiseT, typename U, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT, typename U> requires(traits::is_promise_v<_PromiseT>) | |||||
void promise_yield_value(_PromiseT* promise, U&& val); | void promise_yield_value(_PromiseT* promise, U&& val); | ||||
void set_exception(std::exception_ptr e); | void set_exception(std::exception_ptr e); | ||||
} | } | ||||
auto future_await_resume()->reference_type; | auto future_await_resume()->reference_type; | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
void promise_yield_value(_PromiseT* promise, reference_type val); | void promise_yield_value(_PromiseT* promise, reference_type val); | ||||
void set_exception(std::exception_ptr e); | void set_exception(std::exception_ptr e); | ||||
explicit state_t(bool awaitor) noexcept :state_future_t(awaitor) {} | explicit state_t(bool awaitor) noexcept :state_future_t(awaitor) {} | ||||
public: | public: | ||||
LIBRF_API void future_await_resume(); | LIBRF_API void future_await_resume(); | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
void promise_yield_value(_PromiseT* promise); | void promise_yield_value(_PromiseT* promise); | ||||
LIBRF_API void set_exception(std::exception_ptr e); | LIBRF_API void set_exception(std::exception_ptr e); |
| | ||||
namespace librf | namespace librf | ||||
{ | { | ||||
template<class _PromiseT, typename _Enable> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
void state_future_t::promise_initial_suspend(coroutine_handle<_PromiseT> handler) | void state_future_t::promise_initial_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
assert(this->_scheduler == nullptr); | assert(this->_scheduler == nullptr); | ||||
this->_is_initor = initor_type::Initial; | this->_is_initor = initor_type::Initial; | ||||
} | } | ||||
template<class _PromiseT, typename _Enable> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
void state_future_t::promise_final_suspend(coroutine_handle<_PromiseT> handler) | void state_future_t::promise_final_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
scoped_lock<lock_type> __guard(this->_mtx); | scoped_lock<lock_type> __guard(this->_mtx); | ||||
sch->del_final(this); | sch->del_final(this); | ||||
} | } | ||||
template<class _PromiseT, typename _Enable> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
void state_future_t::future_await_suspend(coroutine_handle<_PromiseT> handler) | void state_future_t::future_await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
_PromiseT& promise = handler.promise(); | _PromiseT& promise = handler.promise(); | ||||
//------------------------------------------------------------------------------------------------ | //------------------------------------------------------------------------------------------------ | ||||
template<class _PromiseT, typename _Enable > | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
void state_t<void>::promise_yield_value(_PromiseT* promise) | void state_t<void>::promise_yield_value(_PromiseT* promise) | ||||
{ | { | ||||
coroutine_handle<_PromiseT> handler = coroutine_handle<_PromiseT>::from_promise(*promise); | coroutine_handle<_PromiseT> handler = coroutine_handle<_PromiseT>::from_promise(*promise); | ||||
//------------------------------------------------------------------------------------------------ | //------------------------------------------------------------------------------------------------ | ||||
template<typename _Ty> | template<typename _Ty> | ||||
template<class _PromiseT, typename U, typename _Enable > | |||||
template<class _PromiseT, typename U> requires(traits::is_promise_v<_PromiseT>) | |||||
void state_t<_Ty>::promise_yield_value(_PromiseT* promise, U&& val) | void state_t<_Ty>::promise_yield_value(_PromiseT* promise, U&& val) | ||||
{ | { | ||||
coroutine_handle<_PromiseT> handler = coroutine_handle<_PromiseT>::from_promise(*promise); | coroutine_handle<_PromiseT> handler = coroutine_handle<_PromiseT>::from_promise(*promise); | ||||
//------------------------------------------------------------------------------------------------ | //------------------------------------------------------------------------------------------------ | ||||
template<typename _Ty> | template<typename _Ty> | ||||
template<class _PromiseT, typename _Enable > | |||||
void state_t<_Ty&>::promise_yield_value(_PromiseT* promise, reference_type val) | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
void state_t<_Ty&>::promise_yield_value(_PromiseT* promise, typename state_t<_Ty&>::reference_type val) | |||||
{ | { | ||||
coroutine_handle<_PromiseT> handler = coroutine_handle<_PromiseT>::from_promise(*promise); | coroutine_handle<_PromiseT> handler = coroutine_handle<_PromiseT>::from_promise(*promise); | ||||
return false; | return false; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend(coroutine_handle<_PromiseT> handler) | bool await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
_PromiseT& promise = handler.promise(); | _PromiseT& promise = handler.promise(); |
LIBRF_API bool on_timeout(); | LIBRF_API bool on_timeout(); | ||||
//将自己加入到通知链表里 | //将自己加入到通知链表里 | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
scheduler_t* on_await_suspend(coroutine_handle<_PromiseT> handler) noexcept | scheduler_t* on_await_suspend(coroutine_handle<_PromiseT> handler) noexcept | ||||
{ | { | ||||
_PromiseT& promise = handler.promise(); | _PromiseT& promise = handler.promise(); | ||||
return _state->_counter.load(std::memory_order_relaxed) == 0; | return _state->_counter.load(std::memory_order_relaxed) == 0; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
void await_suspend(coroutine_handle<_PromiseT> handler) | void await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
_state->on_await_suspend(handler); | _state->on_await_suspend(handler); |
{ | { | ||||
return false; | return false; | ||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||||
bool await_suspend(coroutine_handle<_PromiseT> handler) | bool await_suspend(coroutine_handle<_PromiseT> handler) | ||||
{ | { | ||||
counted_ptr<state_t<void>> _state = state_future_t::_Alloc_state<state_type>(true); | counted_ptr<state_t<void>> _state = state_future_t::_Alloc_state<state_type>(true); |