[exec.run.loop] (original) (raw)

33 Execution control library [exec]

33.12 Execution contexts [exec.ctx]

33.12.1 execution​::​run_loop [exec.run.loop]

33.12.1.1 General [exec.run.loop.general]

A run_loop is an execution resource on which work can be scheduled.

It maintains a thread-safe first-in-first-out queue of work.

Its run member function removes elements from the queue and executes them in a loop on the thread of execution that calls run.

A run_loop instance has an associated countthat corresponds to the number of work items that are in its queue.

Additionally, a run_loop instance has an associated state that can be one ofstarting, running, finishing, or finished.

Concurrent invocations of the member functions of run_loopother than run and its destructor do not introduce data races.

The member functions_pop-front_, push-back, and finishexecute atomically.

Recommended practice: Implementations should use an intrusive queue of operation states to hold the work units to make scheduling allocation-free.

namespace std::execution { class run_loop { class run-loop-scheduler; class run-loop-sender; struct run-loop-opstate-base { virtual void execute() = 0; run_loop* loop; run-loop-opstate-base* next; };template<class Rcvr> using run-loop-opstate = unspecified; run-loop-opstate-base* pop-front(); void push-back(run-loop-opstate-base*); public: run_loop() noexcept; run_loop(run_loop&&) = delete;~run_loop();run-loop-scheduler get_scheduler();void run();void finish();};}

33.12.1.2 Associated types [exec.run.loop.types]

class _run-loop-scheduler_;

run-loop-scheduler is an unspecified type that models scheduler.

Instances of run-loop-scheduler remain valid until the end of the lifetime of the run_loop instance from which they were obtained.

Two instances of run-loop-scheduler compare equal if and only if they were obtained from the same run_loop instance.

Let sch be an expression of type run-loop-scheduler.

The expression schedule(sch)has type run-loop- sender and is not potentially-throwing if sch is not potentially-throwing.

run-loop-sender is an exposition-only type that satisfies sender.

For any type Env,completion_signatures_of_t<_run-loop-sender_, Env> iscompletion_signatures<set_value_t(), set_error_t(exception_ptr), set_stopped_t()>

An instance of run-loop-sender remains valid until the end of the lifetime of its associated run_loop instance.

Let sndr be an expression of type run-loop-sender, let rcvr be an expression such that receiver_of<decltype((_rcvr_)), CS> is truewhere CS is the completion_signatures specialization above.

Let C be either set_value_t or set_stopped_t.

Then:

template<class Rcvr> struct _run-loop-opstate_;

run-loop-opstate<Rcvr>inherits privately and unambiguously from run-loop-opstate-base.

Let o be a non-const lvalue of type run-loop-opstate<Rcvr>, and let REC(o) be a non-const lvalue reference to an instance of type Rcvrthat was initialized with the expression _rcvr_passed to the invocation of connect that returned o.

Then:

33.12.1.3 Constructor and destructor [exec.run.loop.ctor]

Postconditions: count is 0 and state is starting.

Effects: If count is not 0 or if state is running, invokes terminate ([except.terminate]).

Otherwise, has no effects.

33.12.1.4 Member functions [exec.run.loop.members]

_run-loop-opstate-base_* _pop-front_();

Effects: Blocks ([defns.block]) until one of the following conditions is true:

void _push-back_(_run-loop-opstate-base_* item);

Effects: Adds item to the back of the queue and increments count by 1.

Synchronization: This operation synchronizes with the pop-front operation that obtains item.

_run-loop-scheduler_ get_scheduler();

Returns: An instance of _run-loop-scheduler_that can be used to schedule work onto this run_loop instance.

Preconditions: state is either starting or finishing.

Effects: If state is starting, sets the state to running, otherwise leaves state unchanged.

Then, equivalent to:while (auto* op = pop-front()) { op->execute();}

Remarks: When state changes, it does so without introducing data races.

Preconditions: state is either starting or running.

Effects: Changes state to finishing.

Synchronization: finish synchronizes with the pop-front operation that returns nullptr.