this_thread::sync_wait and this_thread::sync_wait_with_variant
are used
to block the current thread of execution
until the specified sender completes and
to return its async result.
sync_wait mandates
that the input sender has exactly one value completion signature.
Let sync-wait-env be the following exposition-only class type:
namespace std::this_thread {structsync-wait-env{
execution::run_loop*loop; // exposition onlyauto query(execution::get_scheduler_t)constnoexcept{returnloop->get_scheduler();
}auto query(execution::get_delegation_scheduler_t)constnoexcept{returnloop->get_scheduler();
}};
}
Let sync-wait-result-type and
sync-wait-with-variant-result-type
be exposition-only alias templates defined as follows:
namespace std::this_thread {template<execution::sender_in<sync-wait-env> Sndr>usingsync-wait-result-type=
optional<execution::value_types_of_t<Sndr, sync-wait-env, decayed-tuple,
type_identity_t>>;
template<execution::sender_in<sync-wait-env> Sndr>usingsync-wait-with-variant-result-type=
optional<execution::value_types_of_t<Sndr, sync-wait-env>>;
}
The name this_thread::sync_wait denotes a customization point object.
For a subexpression sndr, let Sndr be decltype((sndr)).
If sender_in<Sndr, sync-wait-env>
is false,
the expression this_thread::sync_wait(sndr) is ill-formed.
Otherwise, it is expression-equivalent to the following,
except that sndr is evaluated only once:
apply_sender(get-domain-early(sndr), sync_wait, sndr)Mandates:
For a subexpression sndr, let Sndr be decltype((sndr)).
If sender_to<Sndr, sync-wait-receiver<Sndr>>
is false,
the expression sync_wait.apply_sender(sndr) is ill-formed;
otherwise, it is equivalent to:
sync-wait-state<Sndr> state;
auto op = connect(sndr, sync-wait-receiver<Sndr>{&state});
start(op);
state.loop.run();
if(state.error){
rethrow_exception(std::move(state.error));
}return std::move(state.result);
It blocks the current thread of execution ([defns.block])
with forward progress guarantee delegation ([intro.progress])
until the specified sender completes.
The default implementation of sync_wait achieves
forward progress guarantee delegation by providing a run_loop scheduler
via the get_delegation_scheduler query
on the sync-wait-receiver's environment.
The run_loop is driven by the current thread of execution.
The name this_thread::sync_wait_with_variant denotes
a customization point object.
For a subexpression sndr,
let Sndr be decltype(into_variant(sndr)).
If sender_in<Sndr, sync-wait-env>
is false,
this_thread::sync_wait_with_variant(sndr) is ill-formed.
Otherwise, it is expression-equivalent to the following,
except sndr is evaluated only once:
apply_sender(get-domain-early(sndr), sync_wait_with_variant, sndr)Mandates:
If callable<sync_wait_t, Sndr> is false,
the expression sync_wait_with_variant.apply_sender(sndr) is ill-formed.
Otherwise, it is equivalent to:
using result_type =sync-wait-with-variant-result-type<Sndr>;
if(auto opt_value = sync_wait(into_variant(sndr))){return result_type(std::move(get<0>(*opt_value)));
}return result_type(nullopt);
It blocks the current thread of execution ([defns.block])
with forward progress guarantee delegation ([intro.progress])
until the specified sender completes.
The default implementation of sync_wait_with_variant achieves
forward progress guarantee delegation by relying on
the forward progress guarantee delegation provided by sync_wait.