[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 <latch> 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();
