[thread.latch] # 32 Concurrency support library [[thread]](./#thread) ## 32.9 Coordination types [[thread.coord]](thread.coord#thread.latch) ### 32.9.2 Latches [thread.latch] #### [32.9.2.1](#general) General [[thread.latch.general]](thread.latch.general) [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10677) A latch is a thread coordination mechanism that allows any number of threads to block until an expected number of threads arrive at the latch (via the count_down function)[.](#general-1.sentence-1) The expected count is set when the latch is created[.](#general-1.sentence-2) An individual latch is a single-use object; once the expected count has been reached, the latch cannot be reused[.](#general-1.sentence-3) #### [32.9.2.2](#latch.syn) Header synopsis [[latch.syn]](latch.syn) [🔗](#header:%3clatch%3e) namespace std {class latch;} #### [32.9.2.3](#class) Class latch [[thread.latch.class]](thread.latch.class) namespace std {class latch {public:static constexpr ptrdiff_t max() noexcept; constexpr explicit latch(ptrdiff_t expected); ~latch(); latch(const latch&) = delete; latch& operator=(const latch&) = delete; void count_down(ptrdiff_t update = 1); bool try_wait() const noexcept; void wait() const; void arrive_and_wait(ptrdiff_t update = 1); private: ptrdiff_t counter; // *exposition only*};} [1](#class-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10720) A latch maintains an internal counter that is initialized when the latch is created[.](#class-1.sentence-1) Threads can block on the latch object, waiting for counter to be decremented to zero[.](#class-1.sentence-2) [2](#class-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10726) Concurrent invocations of the member functions of latch, other than its destructor, do not introduce data races[.](#class-2.sentence-1) [🔗](#lib:max,latch) `static constexpr ptrdiff_t max() noexcept; ` [3](#class-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10736) *Returns*: The maximum value of counter that the implementation supports[.](#class-3.sentence-1) [🔗](#lib:latch,constructor) `constexpr explicit latch(ptrdiff_t expected); ` [4](#class-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10747) *Preconditions*: expected >= 0 is true andexpected <= max() is true[.](#class-4.sentence-1) [5](#class-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10752) *Effects*: Initializes counter with expected[.](#class-5.sentence-1) [6](#class-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10756) *Throws*: Nothing[.](#class-6.sentence-1) [🔗](#lib:count_down,latch) `void count_down(ptrdiff_t update = 1); ` [7](#class-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10767) *Preconditions*: update >= 0 is true, andupdate <= counter is true[.](#class-7.sentence-1) [8](#class-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10772) *Effects*: Atomically decrements counter by update[.](#class-8.sentence-1) If counter is equal to zero, unblocks all threads blocked on *this[.](#class-8.sentence-2) [9](#class-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10778) *Synchronization*: Strongly happens before the returns from all calls that are unblocked[.](#class-9.sentence-1) [10](#class-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10782) *Throws*: system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#class-10.sentence-1) [11](#class-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10786) *Error conditions*: Any of the error conditions allowed for mutex types ([[thread.mutex.requirements.mutex]](thread.mutex.requirements.mutex "32.6.4.2 Mutex types"))[.](#class-11.sentence-1) [🔗](#lib:try_wait,latch) `bool try_wait() const noexcept; ` [12](#class-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10798) *Returns*: With very low probability false[.](#class-12.sentence-1) Otherwise counter == 0[.](#class-12.sentence-2) [🔗](#lib:wait,latch) `void wait() const; ` [13](#class-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10809) *Effects*: If counter equals zero, returns immediately[.](#class-13.sentence-1) Otherwise, blocks on *this until a call to count_down that decrements counter to zero[.](#class-13.sentence-2) [14](#class-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10816) *Throws*: system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#class-14.sentence-1) [15](#class-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10820) *Error conditions*: Any of the error conditions allowed for mutex types ([[thread.mutex.requirements.mutex]](thread.mutex.requirements.mutex "32.6.4.2 Mutex types"))[.](#class-15.sentence-1) [🔗](#lib:arrive_and_wait,latch) `void arrive_and_wait(ptrdiff_t update = 1); ` [16](#class-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10832) *Effects*: Equivalent to:count_down(update); wait();