/** | /** | ||||
* @brief 获得当前协程绑定的调度器。 | * @brief 获得当前协程绑定的调度器。 | ||||
* @details 立即返回,没有协程切换和等待。\n | * @details 立即返回,没有协程切换和等待。\n | ||||
* 推荐使用 current_scheduler() 宏替代 co_await get_current_scheduler()。 | |||||
* 推荐使用 librf_current_scheduler() 宏替代 co_await get_current_scheduler()。 | |||||
* @return [co_await] scheduler_t* | * @return [co_await] scheduler_t* | ||||
* @note 本函数是librf名字空间下的全局函数。由于doxygen使用上的问题,将之归纳到 get_current_scheduler_awaitor 类下。 | * @note 本函数是librf名字空间下的全局函数。由于doxygen使用上的问题,将之归纳到 get_current_scheduler_awaitor 类下。 | ||||
*/ | */ | ||||
* @return scheduler_t* | * @return scheduler_t* | ||||
* @note 由于doxygen使用上的问题,将之归纳到 get_current_scheduler_awaitor 类下。 | * @note 由于doxygen使用上的问题,将之归纳到 get_current_scheduler_awaitor 类下。 | ||||
*/ | */ | ||||
static scheduler_t* current_scheduler() noexcept; | |||||
static scheduler_t* librf_current_scheduler() noexcept; | |||||
#endif //DOXYGEN_SKIP_PROPERTY | #endif //DOXYGEN_SKIP_PROPERTY | ||||
}; | }; | ||||
/** | /** | ||||
* @brief 获得当前协程绑定的调度器。 | * @brief 获得当前协程绑定的调度器。 | ||||
* @details 立即返回,没有协程切换和等待。\n | * @details 立即返回,没有协程切换和等待。\n | ||||
* 推荐使用 current_scheduler() 宏替代 co_await get_current_scheduler()。 | |||||
* 推荐使用 librf_current_scheduler() 宏替代 co_await get_current_scheduler()。 | |||||
* @return [co_await] scheduler_t* | * @return [co_await] scheduler_t* | ||||
*/ | */ | ||||
inline get_current_scheduler_awaitor get_current_scheduler() noexcept | inline get_current_scheduler_awaitor get_current_scheduler() noexcept | ||||
/** | /** | ||||
* @brief 获得当前协程的跟state指针。 | * @brief 获得当前协程的跟state指针。 | ||||
* @details 立即返回,没有协程切换和等待。\n | * @details 立即返回,没有协程切换和等待。\n | ||||
* 推荐使用 root_state() 宏替代 co_await get_root_state()。 | |||||
* 推荐使用 librf_root_state() 宏替代 co_await get_root_state()。 | |||||
* @return [co_await] state_base_t* | * @return [co_await] state_base_t* | ||||
* @note 本函数是librf名字空间下的全局函数。由于doxygen使用上的问题,将之归纳到 get_root_state_awaitor 类下。 | * @note 本函数是librf名字空间下的全局函数。由于doxygen使用上的问题,将之归纳到 get_root_state_awaitor 类下。 | ||||
*/ | */ | ||||
* @return state_base_t* | * @return state_base_t* | ||||
* @note 由于doxygen使用上的问题,将之归纳到 get_root_state_awaitor 类下。 | * @note 由于doxygen使用上的问题,将之归纳到 get_root_state_awaitor 类下。 | ||||
*/ | */ | ||||
static state_base_t* root_state() noexcept; | |||||
static state_base_t* librf_root_state() noexcept; | |||||
#endif //DOXYGEN_SKIP_PROPERTY | #endif //DOXYGEN_SKIP_PROPERTY | ||||
}; | }; | ||||
/** | /** | ||||
* @brief 获得当前协程的跟state指针。 | * @brief 获得当前协程的跟state指针。 | ||||
* @details 立即返回,没有协程切换和等待。 | * @details 立即返回,没有协程切换和等待。 | ||||
* 推荐使用 root_state() 宏替代 co_await get_root_state()。 | |||||
* 推荐使用 librf_root_state() 宏替代 co_await get_root_state()。 | |||||
* @return [co_await] state_base_t* | * @return [co_await] state_base_t* | ||||
*/ | */ | ||||
inline get_root_state_awaitor get_root_state() noexcept | inline get_root_state_awaitor get_root_state() noexcept | ||||
/** | /** | ||||
* @brief 获得当前协程的task_t指针。 | * @brief 获得当前协程的task_t指针。 | ||||
* @details 立即返回,没有协程切换和等待。 | * @details 立即返回,没有协程切换和等待。 | ||||
* 推荐使用 current_task() 宏替代 co_await get_current_task()。 | |||||
* 推荐使用 librf_current_task() 宏替代 co_await get_current_task()。 | |||||
* @return [co_await] task_t* | * @return [co_await] task_t* | ||||
* @note 本函数是librf名字空间下的全局函数。由于doxygen使用上的问题,将之归纳到 get_current_task_awaitor 类下。 | * @note 本函数是librf名字空间下的全局函数。由于doxygen使用上的问题,将之归纳到 get_current_task_awaitor 类下。 | ||||
*/ | */ | ||||
* @return task_t* | * @return task_t* | ||||
* @note 由于doxygen使用上的问题,将之归纳到 get_current_task_awaitor 类下。 | * @note 由于doxygen使用上的问题,将之归纳到 get_current_task_awaitor 类下。 | ||||
*/ | */ | ||||
static task_t* current_task() noexcept; | |||||
static task_t* librf_current_task() noexcept; | |||||
#endif //DOXYGEN_SKIP_PROPERTY | #endif //DOXYGEN_SKIP_PROPERTY | ||||
}; | }; | ||||
/** | /** | ||||
* @brief 获得当前协程的task_t指针。 | * @brief 获得当前协程的task_t指针。 | ||||
* @details 立即返回,没有协程切换和等待。 | * @details 立即返回,没有协程切换和等待。 | ||||
* 推荐使用 current_task() 宏替代 co_await get_current_task()。 | |||||
* 推荐使用 librf_current_task() 宏替代 co_await get_current_task()。 | |||||
* @return [co_await] task_t* | * @return [co_await] task_t* | ||||
*/ | */ | ||||
inline get_current_task_awaitor get_current_task() noexcept | inline get_current_task_awaitor get_current_task() noexcept |
#define GO (*::librf::this_scheduler()) + [=]()mutable->librf::future_t<> | #define GO (*::librf::this_scheduler()) + [=]()mutable->librf::future_t<> | ||||
#endif | #endif | ||||
#define current_scheduler() (co_await ::librf::get_current_scheduler()) | |||||
#define root_state() (co_await ::librf::get_root_state()) | |||||
#define current_task() (co_await ::librf::get_current_task()) | |||||
#define librf_current_scheduler() (co_await ::librf::get_current_scheduler()) | |||||
#define librf_root_state() (co_await ::librf::get_root_state()) | |||||
#define librf_current_task() (co_await ::librf::get_current_task()) | |||||
#if defined(__clang__) || defined(__GNUC__) | #if defined(__clang__) || defined(__GNUC__) | ||||
#ifndef likely | #ifndef likely |
/** | /** | ||||
* @brief 尝试在协程中加锁。此操作无论成功与否都会立即返回,不会有协程切换。 | * @brief 尝试在协程中加锁。此操作无论成功与否都会立即返回,不会有协程切换。 | ||||
* @details 如果加锁成功,则需要调用co_await unlock()解锁。或者使用unlock(root_state())解锁。\n | |||||
* @details 如果加锁成功,则需要调用co_await unlock()解锁。或者使用unlock(librf_root_state())解锁。\n | |||||
* 如果加锁失败,且要循环尝试加锁,则最好调用co_await yield()让出一次调度。否则,可能造成本调度器死循环。 | * 如果加锁失败,且要循环尝试加锁,则最好调用co_await yield()让出一次调度。否则,可能造成本调度器死循环。 | ||||
* @return [co_await] bool | * @return [co_await] bool | ||||
*/ | */ | ||||
bool try_lock_until(const std::chrono::time_point<_Rep, _Period>& tp, void* unique_address); | bool try_lock_until(const std::chrono::time_point<_Rep, _Period>& tp, void* unique_address); | ||||
/** | /** | ||||
* @brief 在非协程中解锁。立即返回。由于立即返回,也可在协程中如此使用:mtx.unlock(root_state()) | |||||
* @brief 在非协程中解锁。立即返回。由于立即返回,也可在协程中如此使用:mtx.unlock(librf_root_state()) | |||||
* @param unique_address 代表获得锁的拥有者。 | * @param unique_address 代表获得锁的拥有者。 | ||||
*/ | */ | ||||
void unlock(void* unique_address) const; | void unlock(void* unique_address) const; | ||||
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); | ||||
/** | /** | ||||
* @brief 在协程中批量解锁。如果可能,使用unlock(root_state(), mtxs...)来替代。 | |||||
* @brief 在协程中批量解锁。如果可能,使用unlock(librf_root_state(), mtxs...)来替代。 | |||||
* @param mtxs... 需要解锁的锁列表。 | * @param mtxs... 需要解锁的锁列表。 | ||||
* @return [co_await] void | * @return [co_await] void | ||||
*/ | */ | ||||
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); | ||||
/** | /** | ||||
* @brief 在非协程中批量解锁。立即返回。由于立即返回,也可在协程中如此使用:unlock(root_state(), mtxs...) | |||||
* @brief 在非协程中批量解锁。立即返回。由于立即返回,也可在协程中如此使用:unlock(librf_root_state(), mtxs...) | |||||
* @param unique_address 代表获得锁的拥有者。 | * @param unique_address 代表获得锁的拥有者。 | ||||
* @param mtxs... 需要解锁的锁列表。 | * @param mtxs... 需要解锁的锁列表。 | ||||
*/ | */ |
template<class... _Mtxs, typename> | template<class... _Mtxs, typename> | ||||
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, root_state(), mtxs... }; | |||||
batch_unlock_t<_Mtxs...> unlock_guard{ std::adopt_lock, librf_root_state(), mtxs... }; | |||||
co_await detail::mutex_lock_await_lock_impl::_Lock_range(unlock_guard._MAA); | co_await detail::mutex_lock_await_lock_impl::_Lock_range(unlock_guard._MAA); | ||||
co_return std::move(unlock_guard); | co_return std::move(unlock_guard); | ||||
} | } | ||||
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编译器内部错误。 | ||||
mutex_t::_MutexAwaitAssembleT _MAA{ root_state(), mtxs... }; | |||||
mutex_t::_MutexAwaitAssembleT _MAA{ librf_root_state(), mtxs... }; | |||||
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, typename> | ||||
inline future_t<> mutex_t::unlock(_Mtxs&... mtxs) | inline future_t<> mutex_t::unlock(_Mtxs&... mtxs) | ||||
{ | { | ||||
void* unique_address = root_state(); | |||||
void* unique_address = librf_root_state(); | |||||
(mtxs.unlock(unique_address), ...); | (mtxs.unlock(unique_address), ...); | ||||
} | } |
template<class _Rep, class _Period> | template<class _Rep, class _Period> | ||||
inline future_t<> sleep_for(std::chrono::duration<_Rep, _Period> dt_) | inline future_t<> sleep_for(std::chrono::duration<_Rep, _Period> dt_) | ||||
{ | { | ||||
scheduler_t* sch = current_scheduler(); | |||||
scheduler_t* sch = librf_current_scheduler(); | |||||
co_await sleep_for_(std::chrono::duration_cast<std::chrono::system_clock::duration>(dt_), *sch); | co_await sleep_for_(std::chrono::duration_cast<std::chrono::system_clock::duration>(dt_), *sch); | ||||
} | } | ||||
template<class _Clock, class _Duration> | template<class _Clock, class _Duration> | ||||
inline future_t<> sleep_until(std::chrono::time_point<_Clock, _Duration> tp_) | inline future_t<> sleep_until(std::chrono::time_point<_Clock, _Duration> tp_) | ||||
{ | { | ||||
scheduler_t* sch = current_scheduler(); | |||||
scheduler_t* sch = librf_current_scheduler(); | |||||
co_await sleep_until_(std::chrono::time_point_cast<std::chrono::system_clock::duration>(tp_), *sch); | co_await sleep_until_(std::chrono::time_point_cast<std::chrono::system_clock::duration>(tp_), *sch); | ||||
} | } | ||||
template <class Rep, class Period> | template <class Rep, class Period> | ||||
inline future_t<> operator co_await(std::chrono::duration<Rep, Period> dt_) | inline future_t<> operator co_await(std::chrono::duration<Rep, Period> dt_) | ||||
{ | { | ||||
scheduler_t* sch = current_scheduler(); | |||||
scheduler_t* sch = librf_current_scheduler(); | |||||
co_await sleep_for(dt_, *sch); | co_await sleep_for(dt_, *sch); | ||||
} | } | ||||
/** | /** | ||||
* @brief 等待所有的可等待对象完成,不定参数版。 | * @brief 等待所有的可等待对象完成,不定参数版。 | ||||
* @details 当前协程的调度器通过current_scheduler()宏获得,与带调度器参数的版本相比,多一次resumeable function构造,效率可能低一点。 | |||||
* @details 当前协程的调度器通过 librf_current_scheduler() 宏获得,与带调度器参数的版本相比,多一次resumeable function构造,效率可能低一点。 | |||||
* @param args... 所有的可等待对象。要么是_AwaitableT<>类型,要么是返回_AwaitableT<>类型的函数(对象)。 | * @param args... 所有的可等待对象。要么是_AwaitableT<>类型,要么是返回_AwaitableT<>类型的函数(对象)。 | ||||
* @retval [co_await] std::tuple<...>。每个可等待对象的返回值,逐个存入到std::tuple<...>里面。void 返回值,存的是std::ignore。 | * @retval [co_await] std::tuple<...>。每个可等待对象的返回值,逐个存入到std::tuple<...>里面。void 返回值,存的是std::ignore。 | ||||
*/ | */ | ||||
auto when_all(_Awaitable&&... args) | auto when_all(_Awaitable&&... args) | ||||
-> future_t<std::tuple<detail::awaitor_result_t<_Awaitable>...>> | -> future_t<std::tuple<detail::awaitor_result_t<_Awaitable>...>> | ||||
{ | { | ||||
scheduler_t* sch = current_scheduler(); | |||||
scheduler_t* sch = librf_current_scheduler(); | |||||
co_return co_await when_all(*sch, std::forward<_Awaitable>(args)...); | co_return co_await when_all(*sch, std::forward<_Awaitable>(args)...); | ||||
} | } | ||||
/** | /** | ||||
* @brief 等待所有的可等待对象完成,迭代器版。 | * @brief 等待所有的可等待对象完成,迭代器版。 | ||||
* @details 当前协程的调度器通过current_scheduler()宏获得,与带调度器参数的版本相比,多一次resumeable function构造,效率可能低一点。 | |||||
* @details 当前协程的调度器通过 librf_current_scheduler() 宏获得,与带调度器参数的版本相比,多一次resumeable function构造,效率可能低一点。 | |||||
* @param begin 可等待对象容器的起始迭代器。迭代器指向的,要么是_AwaitableT<>类型,要么是返回_AwaitableT<>类型的函数(对象)。 | * @param begin 可等待对象容器的起始迭代器。迭代器指向的,要么是_AwaitableT<>类型,要么是返回_AwaitableT<>类型的函数(对象)。 | ||||
* @param end 可等待对象容器的结束迭代器。 | * @param end 可等待对象容器的结束迭代器。 | ||||
* @retval [co_await] std::vector<>。每个可等待对象的返回值,逐个存入到std::vector<>里面。void 返回值,存的是std::ignore。 | * @retval [co_await] std::vector<>。每个可等待对象的返回值,逐个存入到std::vector<>里面。void 返回值,存的是std::ignore。 | ||||
auto when_all(_Iter begin, _Iter end) | auto when_all(_Iter begin, _Iter end) | ||||
-> future_t<std::vector<detail::awaitor_result_t<decltype(*begin)>>> | -> future_t<std::vector<detail::awaitor_result_t<decltype(*begin)>>> | ||||
{ | { | ||||
scheduler_t* sch = current_scheduler(); | |||||
scheduler_t* sch = librf_current_scheduler(); | |||||
co_return co_await when_all(*sch, begin, end); | co_return co_await when_all(*sch, begin, end); | ||||
} | } | ||||
/** | /** | ||||
* @brief 等待所有的可等待对象完成,容器版。 | * @brief 等待所有的可等待对象完成,容器版。 | ||||
* @details 当前协程的调度器通过current_scheduler()宏获得,与带调度器参数的版本相比,多一次resumeable function构造,效率可能低一点。 | |||||
* @details 当前协程的调度器通过 librf_current_scheduler() 宏获得,与带调度器参数的版本相比,多一次resumeable function构造,效率可能低一点。 | |||||
* @param cont 存访可等待对象的容器。容器内存放的,要么是_AwaitableT<>类型,要么是返回_AwaitableT<>类型的函数(对象)。 | * @param cont 存访可等待对象的容器。容器内存放的,要么是_AwaitableT<>类型,要么是返回_AwaitableT<>类型的函数(对象)。 | ||||
* @retval [co_await] std::vector<>。每个可等待对象的返回值,逐个存入到std::vector<>里面。void 返回值,存的是std::ignore。 | * @retval [co_await] std::vector<>。每个可等待对象的返回值,逐个存入到std::vector<>里面。void 返回值,存的是std::ignore。 | ||||
*/ | */ | ||||
/** | /** | ||||
* @brief 等待任一的可等待对象完成,不定参数版。 | * @brief 等待任一的可等待对象完成,不定参数版。 | ||||
* @details 当前协程的调度器通过current_scheduler()宏获得,与带调度器参数的版本相比,多一次resumeable function构造,效率可能低一点。 | |||||
* @details 当前协程的调度器通过 librf_current_scheduler() 宏获得,与带调度器参数的版本相比,多一次resumeable function构造,效率可能低一点。 | |||||
* @param args... 所有的可等待对象。要么是_AwaitableT<>类型,要么是返回_AwaitableT<>类型的函数(对象)。 | * @param args... 所有的可等待对象。要么是_AwaitableT<>类型,要么是返回_AwaitableT<>类型的函数(对象)。 | ||||
* @retval [co_await] std::pair<intptr_t, std::any>。第一个值指示哪个对象完成了,第二个值存访的对应的返回数据。 | * @retval [co_await] std::pair<intptr_t, std::any>。第一个值指示哪个对象完成了,第二个值存访的对应的返回数据。 | ||||
*/ | */ | ||||
auto when_any(_Awaitable&&... args) | auto when_any(_Awaitable&&... args) | ||||
-> future_t<when_any_pair> | -> future_t<when_any_pair> | ||||
{ | { | ||||
scheduler_t* sch = current_scheduler(); | |||||
scheduler_t* sch = librf_current_scheduler(); | |||||
co_return co_await when_any(*sch, std::forward<_Awaitable>(args)...); | co_return co_await when_any(*sch, std::forward<_Awaitable>(args)...); | ||||
} | } | ||||
/** | /** | ||||
* @brief 等待任一的可等待对象完成,迭代器版。 | * @brief 等待任一的可等待对象完成,迭代器版。 | ||||
* @details 当前协程的调度器通过current_scheduler()宏获得,与带调度器参数的版本相比,多一次resumeable function构造,效率可能低一点。 | |||||
* @details 当前协程的调度器通过 librf_current_scheduler() 宏获得,与带调度器参数的版本相比,多一次resumeable function构造,效率可能低一点。 | |||||
* @param begin 可等待对象容器的起始迭代器。迭代器指向的,要么是_AwaitableT<>类型,要么是返回_AwaitableT<>类型的函数(对象)。 | * @param begin 可等待对象容器的起始迭代器。迭代器指向的,要么是_AwaitableT<>类型,要么是返回_AwaitableT<>类型的函数(对象)。 | ||||
* @param end 可等待对象容器的结束迭代器。 | * @param end 可等待对象容器的结束迭代器。 | ||||
* @retval [co_await] std::pair<intptr_t, std::any>。第一个值指示哪个对象完成了,第二个值存访的对应的返回数据。 | * @retval [co_await] std::pair<intptr_t, std::any>。第一个值指示哪个对象完成了,第二个值存访的对应的返回数据。 | ||||
auto when_any(_Iter begin, _Iter end) | auto when_any(_Iter begin, _Iter end) | ||||
-> future_t<when_any_pair> | -> future_t<when_any_pair> | ||||
{ | { | ||||
scheduler_t* sch = current_scheduler(); | |||||
scheduler_t* sch = librf_current_scheduler(); | |||||
co_return co_await when_any(*sch, begin, end); | co_return co_await when_any(*sch, begin, end); | ||||
} | } | ||||
/** | /** | ||||
* @brief 等待任一的可等待对象完成,容器版。 | * @brief 等待任一的可等待对象完成,容器版。 | ||||
* @details 当前协程的调度器通过current_scheduler()宏获得,与带调度器参数的版本相比,多一次resumeable function构造,效率可能低一点。 | |||||
* @details 当前协程的调度器通过 librf_current_scheduler() 宏获得,与带调度器参数的版本相比,多一次resumeable function构造,效率可能低一点。 | |||||
* @param cont 存访可等待对象的容器。容器内存放的,要么是_AwaitableT<>类型,要么是返回_AwaitableT<>类型的函数(对象)。 | * @param cont 存访可等待对象的容器。容器内存放的,要么是_AwaitableT<>类型,要么是返回_AwaitableT<>类型的函数(对象)。 | ||||
* @retval [co_await] std::pair<intptr_t, std::any>。第一个值指示哪个对象完成了,第二个值存访的对应的返回数据。 | * @retval [co_await] std::pair<intptr_t, std::any>。第一个值指示哪个对象完成了,第二个值存访的对应的返回数据。 | ||||
*/ | */ |
//如果关联的协程被取消了,则触发canceled_exception异常。 | //如果关联的协程被取消了,则触发canceled_exception异常。 | ||||
static future_t<int64_t> async_get_long_with_stop(int64_t val) | static future_t<int64_t> async_get_long_with_stop(int64_t val) | ||||
{ | { | ||||
task_t* task = current_task(); | |||||
task_t* task = librf_current_task(); | |||||
co_return co_await async_get_long_with_stop(task->get_stop_token(), val); | co_return co_await async_get_long_with_stop(task->get_stop_token(), val); | ||||
} | } | ||||
static future_t<> resumable_get_long_switch_scheduler(int64_t val, channel_t<bool> c_done) | static future_t<> resumable_get_long_switch_scheduler(int64_t val, channel_t<bool> c_done) | ||||
{ | { | ||||
std::cout << "thread = " << std::this_thread::get_id(); | std::cout << "thread = " << std::this_thread::get_id(); | ||||
std::cout << ", scheduler = " << current_scheduler(); | |||||
std::cout << ", scheduler = " << librf_current_scheduler(); | |||||
std::cout << ", value = " << val << std::endl; | std::cout << ", value = " << val << std::endl; | ||||
co_await via(sch_in_thread); | co_await via(sch_in_thread); | ||||
val = co_await async_get_long_switch_scheduler(val); | val = co_await async_get_long_switch_scheduler(val); | ||||
std::cout << "thread = " << std::this_thread::get_id(); | std::cout << "thread = " << std::this_thread::get_id(); | ||||
std::cout << ", scheduler = " << current_scheduler(); | |||||
std::cout << ", scheduler = " << librf_current_scheduler(); | |||||
std::cout << ", value = " << val << std::endl; | std::cout << ", value = " << val << std::endl; | ||||
co_await via(sch_in_main); | co_await via(sch_in_main); | ||||
val = co_await async_get_long_switch_scheduler(val); | val = co_await async_get_long_switch_scheduler(val); | ||||
std::cout << "thread = " << std::this_thread::get_id(); | std::cout << "thread = " << std::this_thread::get_id(); | ||||
std::cout << ", scheduler = " << current_scheduler(); | |||||
std::cout << ", scheduler = " << librf_current_scheduler(); | |||||
std::cout << ", value = " << val << std::endl; | std::cout << ", value = " << val << std::endl; | ||||
co_await via(sch_in_thread); | co_await via(sch_in_thread); | ||||
val = co_await async_get_long_switch_scheduler(val); | val = co_await async_get_long_switch_scheduler(val); | ||||
std::cout << "thread = " << std::this_thread::get_id(); | std::cout << "thread = " << std::this_thread::get_id(); | ||||
std::cout << ", scheduler = " << current_scheduler(); | |||||
std::cout << ", scheduler = " << librf_current_scheduler(); | |||||
std::cout << ", value = " << val << std::endl; | std::cout << ", value = " << val << std::endl; | ||||
co_await via(sch_in_thread); //fake switch | co_await via(sch_in_thread); //fake switch | ||||
val = co_await async_get_long_switch_scheduler(val); | val = co_await async_get_long_switch_scheduler(val); | ||||
std::cout << "thread = " << std::this_thread::get_id(); | std::cout << "thread = " << std::this_thread::get_id(); | ||||
std::cout << ", scheduler = " << current_scheduler(); | |||||
std::cout << ", scheduler = " << librf_current_scheduler(); | |||||
std::cout << ", value = " << val << std::endl; | std::cout << ", value = " << val << std::endl; | ||||
(void)c_done.write(true); | (void)c_done.write(true); |