Skip to content

Commit 122ed83

Browse files
committed
fixup: all of 34.9
1 parent 841de94 commit 122ed83

File tree

1 file changed

+252
-0
lines changed

1 file changed

+252
-0
lines changed

source/exec.tex

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4382,6 +4382,258 @@
43824382
});
43834383
\end{codeblock}
43844384

4385+
\rSec2[exec.consumers]{Sender consumers}
4386+
4387+
\rSec3[exec.sync.wait]{\tcode{this_thread::sync_wait}}
4388+
4389+
\pnum
4390+
\tcode{this_thread::sync_wait} and \tcode{this_thread::sync_wait_with_variant}
4391+
are used
4392+
to block the current thread of execution
4393+
until the specified sender completes and
4394+
to return its async result.
4395+
\tcode{sync_wait} mandates
4396+
that the input sender has exactly one value completion signature.
4397+
4398+
\pnum
4399+
Let \exposid{sync-wait-env} be the following exposition-only class type:
4400+
\begin{codeblock}
4401+
namespace std::this_thread {
4402+
struct @\exposid{sync-wait-env}@ {
4403+
execution::run_loop* @\exposid{loop}@; // \expos
4404+
4405+
auto query(execution::get_scheduler_t) const noexcept {
4406+
return @\exposid{loop}@->get_scheduler();
4407+
}
4408+
4409+
auto query(execution::get_delegation_scheduler_t) const noexcept {
4410+
return @\exposid{loop}@->get_scheduler();
4411+
}
4412+
};
4413+
}
4414+
\end{codeblock}
4415+
4416+
\pnum
4417+
Let \exposid{sync-wait-result-type} and
4418+
\exposid{sync-wait-with-variant-result-type}
4419+
be exposition-only alias templates defined as follows:
4420+
\begin{codeblock}
4421+
namespace std::this_thread {
4422+
template<execution::@\libconcept{sender_in}@<@\exposid{sync-wait-env}@> Sndr>
4423+
using sync-wait-result-type =
4424+
optional<execution::value_types_of_t<Sndr, @\exposid{sync-wait-env}@, @\exposid{decayed-tuple}@,
4425+
type_identity_t>>;
4426+
4427+
template<execution::sender_in<sync-wait-env> Sndr>
4428+
using @\exposid{sync-wait-with-variant-result-type}@ =
4429+
optional<execution::value_types_of_t<Sndr, @\exposid{sync-wait-env}@>>;
4430+
}
4431+
\end{codeblock}
4432+
4433+
\pnum
4434+
The name \tcode{this_thread::sync_wait} denotes a customization point object.
4435+
For a subexpression \tcode{sndr}, let \tcode{Sndr} be \tcode{decltype((sndr))}.
4436+
If \tcode{\libconcept{sender_in}<Sndr, \exposid{sync-wait-env}>}
4437+
is \tcode{false},
4438+
the expression \tcode{this_thread::sync_wait(sndr)} is ill-formed.
4439+
Otherwise, it is expression-equivalent to the following,
4440+
except that \tcode{sndr} is evaluated only once:
4441+
\begin{codeblock}
4442+
apply_sender(@\exposid{get-domain-early}@(sndr), sync_wait, sndr)
4443+
\end{codeblock}
4444+
\mandates
4445+
\begin{itemize}
4446+
\item
4447+
The type \tcode{\exposid{sync-wait-result-type}<Sndr>} is well-formed.
4448+
\item
4449+
\tcode{\libconcept{same_as}<decltype($e$), \exposid{sync-wait-result-type}<Sndr>>}
4450+
is \tcode{true}, where $e$ is the apply_sender expression above.
4451+
\end{itemize}
4452+
4453+
\pnum
4454+
Let \exposid{sync-wait-state} and \exposid{sync-wait-receiver}
4455+
be the following exposition-only class templates:
4456+
\begin{codeblock}
4457+
namespace std::this_thread {
4458+
template<class Sndr>
4459+
struct @\exposid{sync-wait-state}@ { // \expos
4460+
execution::run_loop @\exposid{loop}@; // \expos
4461+
exception_ptr @\exposid{error}@; // \expos
4462+
@\exposid{sync-wait-result-type}@<Sndr> @\exposid{result}@; // \expos
4463+
};
4464+
4465+
template<class Sndr>
4466+
struct @\exposid{sync-wait-receiver}@ { // \expos
4467+
using receiver_concept = execution::receiver_t;
4468+
@\exposid{sync-wait-state}@<Sndr>* @\exposid{state}@; // \expos
4469+
4470+
template<class... Args>
4471+
void set_value(Args&&... args) && noexcept;
4472+
4473+
template<class Error>
4474+
void set_error(Error&& err) && noexcept;
4475+
4476+
void set_stopped() && noexcept;
4477+
4478+
@\exposid{sync-wait-env}@ get_env() const noexcept { return {&@\exposid{state}@->@\exposid{loop}@}; }
4479+
};
4480+
}
4481+
\end{codeblock}
4482+
4483+
\begin{itemdecl}
4484+
template<class... Args>
4485+
void set_value(Args&&... args) && noexcept;
4486+
\end{itemdecl}
4487+
4488+
\begin{itemdescr}
4489+
\pnum
4490+
\effects
4491+
Equivalent to:
4492+
\begin{codeblock}
4493+
try {
4494+
@\exposid{state}@->@\exposid{result}@.emplace(std::forward<Args>(args)...);
4495+
} catch (...) {
4496+
@\exposid{state}@->@\exposid{error}@ = current_exception();
4497+
}
4498+
@\exposid{state}@->@\exposid{loop}@.finish();
4499+
\end{codeblock}
4500+
\end{itemdescr}
4501+
4502+
\begin{itemdecl}
4503+
template<class Error>
4504+
void set_error(Error&& err) && noexcept;
4505+
\end{itemdecl}
4506+
4507+
\begin{itemdescr}
4508+
\pnum
4509+
\effects
4510+
Equivalent to:
4511+
\begin{codeblock}
4512+
@\exposid{state}@->@\exposid{error}@ = @\exposid{AS-EXCEPT-PTR}@(std::forward<Error>(err)); // see \ref{exec.general}
4513+
@\exposid{state}@->@\exposid{loop}@.finish();
4514+
\end{codeblock}
4515+
\end{itemdescr}
4516+
4517+
\begin{itemdecl}
4518+
void set_stopped() && noexcept;
4519+
\end{itemdecl}
4520+
4521+
\begin{itemdescr}
4522+
\pnum
4523+
\effects
4524+
Equivalent to \tcode{\exposid{state}->\exposid{loop}.finish()}.
4525+
\end{itemdescr}
4526+
4527+
\pnum
4528+
For a subexpression \tcode{sndr}, let \tcode{Sndr} be \tcode{decltype((sndr))}.
4529+
If \tcode{\exposconcept{sender_to}<Sndr, \exposid{sync-wait-receiver}<\linebreak Sndr>>}
4530+
is \tcode{false},
4531+
the expression \tcode{sync_wait.apply_sender(sndr)} is ill-formed;
4532+
otherwise, it is equivalent to:
4533+
\begin{codeblock}
4534+
@\exposid{sync-wait-state}@<Sndr> state;
4535+
auto op = connect(sndr, @\exposid{sync-wait-receiver}@<Sndr>{&state});
4536+
start(op);
4537+
4538+
state.@\exposid{loop}@.run();
4539+
if (state.@\exposid{error}@) {
4540+
rethrow_exception(std::move(state.error));
4541+
}
4542+
return std::move(state.@\exposid{result}@);
4543+
\end{codeblock}
4544+
4545+
\pnum
4546+
The behavior of \tcode{this_thread::sync_wait(sndr)} is undefined unless:
4547+
\begin{itemize}
4548+
\item
4549+
It blocks the current thread of execution\iref{defns.block}
4550+
with forward progress guarantee delegation\iref{intro.progress}
4551+
until the specified sender completes.
4552+
\begin{note}
4553+
The default implementation of \tcode{sync_wait} achieves
4554+
forward progress guarantee delegation by providing a \tcode{run_loop} scheduler
4555+
via the \tcode{get_delegation_scheduler} query
4556+
on the \exposid{sync-wait-receiver}'s environment.
4557+
The \tcode{run_loop} is driven by the current thread of execution.
4558+
\end{note}
4559+
\item
4560+
It returns the specified sender's async results as follows:
4561+
\begin{itemize}
4562+
\item
4563+
For a value completion,
4564+
the result datums are returned in
4565+
a \tcode{tuple} in an engaged \tcode{optional} object.
4566+
\item
4567+
For an error completion, an exception is thrown.
4568+
\item
4569+
For a stopped completion, a disengaged \tcode{optional} object is returned.
4570+
\end{itemize}
4571+
\end{itemize}
4572+
4573+
\rSec3[exec.sync.wait.var]{\tcode{this_thread::sync_wait_with_variant}}
4574+
4575+
\pnum
4576+
The name \tcode{this_thread::sync_wait_with_variant} denotes
4577+
a customization point object.
4578+
For a subexpression \tcode{sndr},
4579+
let \tcode{Sndr} be \tcode{decltype(into_variant(sndr))}.
4580+
If \tcode{\libconcept{sender_in}<Sndr, \exposid{sync-wait-env}>}
4581+
is \tcode{false},
4582+
\tcode{this_thread::sync_wait_with_variant(sndr)} is ill-formed.
4583+
Otherwise, it is expression-equivalent to the following,
4584+
except \tcode{sndr} is evaluated only once:
4585+
\begin{codeblock}
4586+
apply_sender(@\exposid{get-domain-early}@(sndr), sync_wait_with_variant, sndr)
4587+
\end{codeblock}
4588+
\mandates
4589+
\begin{itemize}
4590+
\item
4591+
The type \tcode{\exposid{sync-wait-with-variant-result-type}<Sndr>}
4592+
is well-formed.
4593+
\item
4594+
\tcode{\libconcept{same_as}<decltype($e$), \exposid{sync-wait-with-variant-result-type}<Sndr>>}
4595+
is \tcode{true}, where $e$ is the \tcode{ap\-ply_sender} expression above.
4596+
\end{itemize}
4597+
4598+
\pnum
4599+
If \tcode{\exposconcept{callable}<sync_wait_t, Sndr>} is \tcode{false},
4600+
the expression \tcode{sync_wait_with_variant.apply_sender(\linebreak sndr)} is ill-formed.
4601+
Otherwise, it is equivalent to:
4602+
\begin{codeblock}
4603+
using result_type = @\exposid{sync-wait-with-variant-result-type}@<Sndr>;
4604+
if (auto opt_value = sync_wait(into_variant(sndr))) {
4605+
return result_type(std::move(get<0>(*opt_value)));
4606+
}
4607+
return result_type(nullopt);
4608+
\end{codeblock}
4609+
4610+
\pnum
4611+
The behavior of \tcode{this_thread::sync_wait_with_variant(sndr)}
4612+
is undefined unless:
4613+
\begin{itemize}
4614+
\item
4615+
It blocks the current thread of execution\iref{defns.block}
4616+
with forward progress guarantee delegation\iref{intro.progress}
4617+
until the specified sender completes.
4618+
\begin{note}
4619+
The default implementation of \tcode{sync_wait_with_variant} achieves
4620+
forward progress guarantee delegation by relying on
4621+
the forward progress guarantee delegation provided by \tcode{sync_wait}.
4622+
\end{note}
4623+
\item
4624+
It returns the specified sender's async results as follows:
4625+
\begin{itemize}
4626+
\item
4627+
For a value completion,
4628+
the result datums are returned in an engaged \tcode{optional} object
4629+
that contains a \tcode{variant} of \tcode{tuple}s.
4630+
\item
4631+
For an error completion, an exception is thrown.
4632+
\item
4633+
For a stopped completion, a disengaged \tcode{optional} object is returned.
4634+
\end{itemize}
4635+
\end{itemize}
4636+
43854637
\rSec1[exec.util]{Sender/receiver utilities}
43864638

43874639
\rSec1[exec.ctx]{Execution contexts}

0 commit comments

Comments
 (0)