Closed GorNishanov closed 1 year ago
Repro:
#include <exec/async_scope.hpp> #include <exec/static_thread_pool.hpp> #include <exec/task.hpp> #include <iostream> #include <stdexec/execution.hpp> exec::task<void> coro() { auto stop_token = co_await stdexec::get_stop_token(); std::cout << "stop possible: " << stop_token.stop_possible() << "\n"; } int main() { exec::static_thread_pool pool(1); exec::async_scope scope; scope.spawn(stdexec::on(pool.get_scheduler(), coro())); stdexec::sync_wait(scope.on_empty()); }
Equivalent code in libunifex works.
It seems that:
template <__scheduler_affinity _Affinity, __indirect_stop_token_provider _ParentPromise> explicit __default_awaiter_context( __default_task_context_impl<_Affinity>& __self, _ParentPromise& __parent) { if constexpr (_Affinity == __scheduler_affinity::__sticky) { __check_parent_promise_has_scheduler<_ParentPromise>(); __self.__scheduler_ = get_scheduler(get_env(__parent)); } // Register a callback that will request stop on this basic_task's // stop_source when stop is requested on the parent coroutine's stop // token. using __stop_token_t = stop_token_of_t< env_of_t<_ParentPromise>>; using __stop_callback_t = typename __stop_token_t::template callback_type<__forward_stop_request>; if constexpr (std::same_as<__stop_token_t, in_place_stop_token>) { __self.__stop_token_ = get_stop_token(get_env(__parent)); // -------------------vvv here we are getting never_stop_token token } else if (auto __token = get_stop_token(get_env(__parent)); __token.stop_possible()) { __stop_callback_.emplace<__stop_callback_t>( std::move(__token), __forward_stop_request{__stop_source_}); __self.__stop_token_ = __stop_source_.get_token(); } } in_place_stop_source __stop_source_{}; std::any __stop_callback_{}; };
Fixed by #974. Thanks for the report, Gor!
Repro:
Equivalent code in libunifex works.
It seems that: