[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*}; templateusing *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(); };}