[exec.run.loop.general]

# 33 Execution control library [[exec]](./#exec)

## 33.12 Execution contexts [[exec.ctx]](exec.ctx#exec.run.loop.general)

### 33.12.1 execution​::​run_loop [[exec.run.loop]](exec.run.loop#general)

#### 33.12.1.1 General [exec.run.loop.general]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6321)

A run_loop is an execution resource on which work can be scheduled[.](#1.sentence-1)

It maintains a thread-safe first-in-first-out queue of work[.](#1.sentence-2)

Its run member function removes elements from the queue and
executes them in a loop on the thread of execution that calls run[.](#1.sentence-3)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6327)

A run_loop instance has an associated [*count*](#def:count "33.12.1.1 General [exec.run.loop.general]") that corresponds to the number of work items that are in its queue[.](#2.sentence-1)

Additionally, a run_loop instance has an associated state
that can be one of[*starting*](#def:starting "33.12.1.1 General [exec.run.loop.general]"), [*running*](#def:running "33.12.1.1 General [exec.run.loop.general]"), [*finishing*](#def:finishing "33.12.1.1 General [exec.run.loop.general]"), or [*finished*](#def:finished "33.12.1.1 General [exec.run.loop.general]")[.](#2.sentence-2)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6334)

Concurrent invocations of the member functions of run_loop other than run and its destructor do not introduce data races[.](#3.sentence-1)

The member functions*pop-front*, *push-back*, and finish execute atomically[.](#3.sentence-2)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6341)

*Recommended practice*: Implementations should use an intrusive queue of operation states
to hold the work units to make scheduling allocation-free[.](#4.sentence-1)

namespace std::execution {class [run_loop](#lib:run_loop "33.12.1.1 General [exec.run.loop.general]") {// [[exec.run.loop.types]](exec.run.loop.types "33.12.1.2 Associated types"), associated typesclass *run-loop-scheduler*; // *exposition only*class *run-loop-sender*; // *exposition only*struct *run-loop-opstate-base* { // *exposition only*virtual void *execute*() = 0; // *exposition only* run_loop* *loop*; // *exposition only**run-loop-opstate-base** *next*; // *exposition only*}; template<class Rcvr>using *run-loop-opstate* = *unspecified*; // *exposition only*// [[exec.run.loop.members]](exec.run.loop.members "33.12.1.4 Member functions"), member functions*run-loop-opstate-base** *pop-front*(); // *exposition only*void *push-back*(*run-loop-opstate-base**); // *exposition only*public:// [[exec.run.loop.ctor]](exec.run.loop.ctor "33.12.1.3 Constructor and destructor"), constructor and destructor run_loop() noexcept;
 run_loop(run_loop&&) = delete; ~run_loop(); // [[exec.run.loop.members]](exec.run.loop.members "33.12.1.4 Member functions"), member functions*run-loop-scheduler* get_scheduler(); void run(); void finish(); };}
