stop_token is not propagated into exec::task
GorNishanov opened this issue · 1 comments
GorNishanov commented
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_{};
};
ericniebler commented
Fixed by #974. Thanks for the report, Gor!