Skip to content

Commit 12ce108

Browse files
committed
more scheduler affinity integration
1 parent d280692 commit 12ce108

7 files changed

Lines changed: 51 additions & 9 deletions

File tree

include/stdexec/__detail/__env.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ namespace stdexec {
248248
template <class _Env>
249249
constexpr auto operator()(const _Env&) const noexcept {
250250
if constexpr (tag_invocable<__is_scheduler_affine_t, const _Env&>) {
251-
using _Result = tag_invoke_result_t<__is_scheduler_affine_t, const _Env&>;
251+
using _Result = __decay_t<tag_invoke_result_t<__is_scheduler_affine_t, const _Env&>>;
252252
static_assert(__same_as<decltype(__v<_Result>), const bool>);
253253
return _Result();
254254
} else {

include/stdexec/__detail/__just.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ namespace stdexec {
3434
struct __impl : __sexpr_defaults {
3535
using __tag_t = typename _JustTag::__tag_t;
3636

37+
static constexpr auto get_attrs = [](__ignore) noexcept {
38+
return prop{__is_scheduler_affine_t{}, std::true_type{}};
39+
};
40+
3741
static constexpr auto get_completion_signatures =
3842
[]<class _Sender>(_Sender&&, auto&&...) noexcept {
3943
static_assert(sender_expr_for<_Sender, _JustTag>);

include/stdexec/__detail/__let.hpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -269,25 +269,33 @@ namespace stdexec {
269269
__in_which_let_msg<_Set>,
270270
"The senders returned by Function do not all share a common domain"_mstr>;
271271

272-
template <class _Set>
272+
template <class _Set, class _Sched>
273273
struct __try_common_domain_fn {
274274
struct __error_fn {
275275
template <class... _Senders>
276276
using __f = __mexception<__no_common_domain_t<_Set>, _WITH_SENDERS_<_Senders...>>;
277277
};
278278

279+
// If a sender is "scheduler affine", then it will complete on the same execution
280+
// context on which it was started (e.g., just(42)). In this case, the domain of the
281+
// scheduler is the domain of the sender.
282+
template <class... _Senders>
283+
using __common_domain_t = //
284+
__domain::__common_domain_t<
285+
__if_c<__is_scheduler_affine<_Senders>, schedule_result_t<_Sched>, _Senders>...>;
286+
279287
template <class... _Senders>
280-
using __f = __mcall<__mtry_catch_q<__domain::__common_domain_t, __error_fn>, _Senders...>;
288+
using __f = __mcall<__mtry_catch_q<__common_domain_t, __error_fn>, _Senders...>;
281289
};
282290

283291
// Compute all the domains of all the result senders and make sure they're all the same
284-
template <class _Set, class _Child, class _Fun, class _Env, class _Sched>
292+
template <class _Set, class _Child, class _Fun, class _Sched, class... _Env>
285293
using __result_domain_t = //
286294
__gather_completions<
287295
_Set,
288-
__completion_signatures_of_t<_Child, _Env>,
289-
__result_sender_fn<_Set, _Fun, _Sched, _Env>,
290-
__try_common_domain_fn<_Set>>;
296+
__completion_signatures_of_t<_Child, _Env...>,
297+
__result_sender_fn<_Set, _Fun, _Sched, _Env...>,
298+
__try_common_domain_fn<_Set, _Sched>>;
291299

292300
template <class _LetTag, class _Env>
293301
auto __mk_transform_env_fn(_Env&& __env) noexcept {
@@ -320,7 +328,7 @@ namespace stdexec {
320328
return __completions_t();
321329
} else {
322330
using _Sched = __completion_sched<_Child, _Set>;
323-
using _Domain = __result_domain_t<_Set, _Child, _Fun, _Env, _Sched>;
331+
using _Domain = __result_domain_t<_Set, _Child, _Fun, _Sched, _Env>;
324332

325333
if constexpr (__merror<_Domain>) {
326334
return _Domain();
@@ -443,8 +451,19 @@ namespace stdexec {
443451
template <class _Set, class _Domain>
444452
struct __let_impl : __sexpr_defaults {
445453
static constexpr auto get_attrs = //
446-
[]<class _Child>(__ignore, const _Child& __child) noexcept {
454+
[]<class _Fun, class _Child>(const _Fun&, const _Child& __child) noexcept {
455+
if constexpr (!same_as<_Domain, dependent_domain>) {
447456
return __env::__join(prop{get_domain, _Domain()}, stdexec::get_env(__child));
457+
} else {
458+
using _Sched = __completion_sched<_Child, _Set>;
459+
using _Domain2 = __result_domain_t<_Set, _Child, _Fun, _Sched>;
460+
461+
if constexpr (__merror<_Domain2>) {
462+
return __env::__join(prop{get_domain, dependent_domain()}, stdexec::get_env(__child));
463+
} else {
464+
return __env::__join(prop{get_domain, _Domain2()}, stdexec::get_env(__child));
465+
}
466+
}
448467
};
449468

450469
static constexpr auto get_completion_signatures = //

include/stdexec/__detail/__read_env.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ namespace stdexec {
8383
using __completions_t =
8484
__minvoke<__mtry_catch_q<__read::__completions_t, __q<__query_failed_error>>, _Tag, _Env>;
8585

86+
static constexpr auto get_attrs = [](__ignore) noexcept {
87+
return prop{__is_scheduler_affine_t{}, std::true_type{}};
88+
};
89+
8690
static constexpr auto get_completion_signatures = //
8791
[]<class _Self, class _Env>(const _Self&, _Env&&) noexcept
8892
-> __completions_t<__data_of<_Self>, _Env> {

include/stdexec/__detail/__then.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ namespace stdexec {
6969
};
7070

7171
struct __then_impl : __sexpr_defaults {
72+
static constexpr auto get_attrs = //
73+
[]<class _Child>(__ignore, const _Child& __child) noexcept {
74+
return __env::__join(
75+
prop{__is_scheduler_affine_t{}, __mbool<__is_scheduler_affine<_Child>>{}},
76+
stdexec::get_env(__child));
77+
};
78+
7279
static constexpr auto get_completion_signatures = //
7380
[]<class _Sender, class... _Env>(_Sender&&, _Env&&...) noexcept
7481
-> __completions_t<__decay_t<__data_of<_Sender>>, __child_of<_Sender>, _Env...> {

include/stdexec/__detail/__write_env.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ namespace stdexec {
5353
};
5454

5555
struct __write_env_impl : __sexpr_defaults {
56+
static constexpr auto get_attrs = //
57+
[]<class _Child>(__ignore, const _Child& __child) noexcept {
58+
return __env::__join(
59+
prop{__is_scheduler_affine_t{}, __mbool<__is_scheduler_affine<_Child>>{}},
60+
stdexec::get_env(__child));
61+
};
62+
5663
static constexpr auto get_env = //
5764
[](__ignore, const auto& __state, const auto& __rcvr) noexcept {
5865
return __env::__join(__state, stdexec::get_env(__rcvr));

test/stdexec/algos/factories/test_read.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ namespace {
2525
using Sndr = decltype(sndr);
2626
static_assert(ex::sender<Sndr>);
2727
static_assert(!ex::sender_in<Sndr>);
28+
static_assert(ex::__is_scheduler_affine<Sndr>);
2829
}
2930
} // namespace

0 commit comments

Comments
 (0)