diff --git a/include/stdexec/__detail/__task_scheduler.hpp b/include/stdexec/__detail/__task_scheduler.hpp index 476a2591d..5dc58b95d 100644 --- a/include/stdexec/__detail/__task_scheduler.hpp +++ b/include/stdexec/__detail/__task_scheduler.hpp @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2026 NVIDIA Corporation * * Licensed under the Apache License Version 2.0 with LLVM Exceptions @@ -847,14 +847,32 @@ namespace STDEXEC if (__value_type == __mtypeid) { auto& __val = *static_cast*>(__dest); - if constexpr (__callable>) + + constexpr bool may_as_task_scheduler = [] { - __val.emplace(get_start_scheduler(get_env(__rcvr_))); - } - else + if constexpr (__callable>) + { + return __std::constructible_from< + task_scheduler, + __call_result_t>>; + } + else + { + return false; + } + }(); + + if constexpr (may_as_task_scheduler) { - __val.emplace(inline_scheduler{}); + try + { + __val.emplace(get_start_scheduler(get_env(__rcvr_))); + return; + } + catch (...) + {} } + __val.emplace(inline_scheduler{}); } } } // namespace __detail diff --git a/test/stdexec/schedulers/test_parallel_scheduler.cpp b/test/stdexec/schedulers/test_parallel_scheduler.cpp index 76bf85cc6..a206aa3e8 100644 --- a/test/stdexec/schedulers/test_parallel_scheduler.cpp +++ b/test/stdexec/schedulers/test_parallel_scheduler.cpp @@ -140,6 +140,13 @@ TEST_CASE("simple chain task on parallel scheduler", "[scheduler][parallel_sched (void) snd2; } +TEST_CASE("parallel scheduler used in an already scheduled environment", + "[scheduler][parallel_scheduler]") +{ + auto snd = ex::schedule(ex::get_parallel_scheduler()); + ex::sync_wait(ex::starts_on(ex::get_parallel_scheduler(), snd)); +} + TEST_CASE("checks stop_token before starting the work", "[scheduler][parallel_scheduler]") { STDEXEC::parallel_scheduler sched = STDEXEC::get_parallel_scheduler();