This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Resolved status.

### 1498. Unclear specification for [thread.condition]

Section: 33.7 [thread.condition] Status: Resolved Submitter: Switzerland Opened: 2010-08-25 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [thread.condition].

View all issues with Resolved status.

Discussion:

Addresses CH-29

It is unclear if a spurious wake-up during the loop and reentering of the blocked state due to a repeated execution of the loop will adjust the timer of the blocking with the respect to the previously specified `rel_time` value.

[ Resolution proposed by ballot comment: ]

> Make it clear (e.g. by a note) that when reexecuting the loop the waiting time when blocked will be adjusted with respect to the elapsed time of the previous loop executions.

[ 2010-08-13 Peter Sommerlad comments and provides wording: ]

> Problem: It is unclear if a spurious wake-up during the loop and re-entering of the blocked state due to a repeated execution of the loop will adjust the timer of the blocking with the respect to the previously specified `rel_time` value.

> Proposed Resolution from CH29:

> Make it clear (e.g. by a note) that when re-executing the loop the waiting time when blocked will be adjusted with respect to the elapsed time of the previous loop executions.

> Discussion in Rapperswil:

> Assuming the introduction of a mandatory `steady_clock` proposed by US-181 to the FCD the specification of `condition_variable::wait_for` can be defined in terms of `wait_until` using the `steady_clock`. This is also interleaving with US-181, because that touches the same paragraph (30.5.1 p 25, p34 and 30.5.2 p 20, p 28 in n3092.pdf)

> (The "as if" in the proposed solutions should be confirmed by the standardization terminology experts)

[ 2010-11 Batavia: Resolved by applying n3191 ]

> 1. Change 33.7.4 [thread.condition.condvar] paragraph 25, `wait_for` Effects as indicated:

>    >     template <class Rep, class Period>
>    >     cv_status wait_for(unique_lock<mutex>& lock,
>    >       const chrono::duration<Rep, Period>& rel_time);

>    > [..]

>    > 25 Effects: as if

>    > >     return wait_until(lock, chrono::steady_clock::now() + rel_time);

>    > - Atomically calls `lock.unlock()` and blocks on `*this`.
>    > - When unblocked, calls `lock.lock()` (possibly blocking on the lock), then returns.
>    > - The function will unblock when signaled by a call to `notify_one()` or a call to `notify_all()`, by the elapsed time `rel_time` passing (30.2.4), or spuriously.
>    > - If the function exits via an exception, `lock.lock()` shall be called prior to exiting the function scope.

> 2. Change 33.7.4 [thread.condition.condvar] paragraph 34, `wait_for` with predicate Effects as indicated:

>    >     template <class Rep, class Period, class Predicate>
>    >     bool wait_for(unique_lock<mutex>& lock,
>    >       const chrono::duration<Rep, Period>& rel_time,
>    >       Predicate pred);

>    > [..]

>    > 34 Effects: as if

>    > >     return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));

>    > - Executes a loop: Within the loop the function first evaluates `pred()` and exits the loop if the result is `true`.
>    > - Atomically calls `lock.unlock()` and blocks on `*this`.
>    > - When unblocked, calls `lock.lock()` (possibly blocking on the lock).
>    > - The function will unblock when signaled by a call to `notify_one()` or a call to `notify_all()`, by the elapsed time `rel_time` passing (30.2.4), or spuriously.
>    > - If the function exits via an exception, `lock.lock()` shall be called prior to exiting the function scope.
>    > - The loop terminates when `pred()` returns `true` or when the time duration specified by `rel_time` has elapsed.

> 3. Change 33.7.5 [thread.condition.condvarany] paragraph 20, `wait_for` Effects as indicated:

>    >     template <class Lock, class Rep, class Period>
>    >     cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);

>    > 20 Effects: as if

>    > >     return wait_until(lock, chrono::steady_clock::now() + rel_time);

>    > - Atomically calls `lock.unlock()` and blocks on `*this`.
>    > - When unblocked, calls `lock.lock()` (possibly blocking on the lock), then returns.
>    > - The function will unblock when signaled by a call to `notify_one()` or a call to `notify_all()`, by the elapsed time `rel_time` passing (30.2.4), or spuriously.
>    > - If the function exits via an exception, `lock.unlock()` shall be called prior to exiting the function scope.

> 4. Change 33.7.5 [thread.condition.condvarany] paragraph 28, `wait_for` with predicate Effects as indicated:

>    >     template <class Lock, class Rep, class Period, class Predicate>
>    >     bool wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred);

>    > 28 Effects: as if

>    > >     return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));

>    > - Executes a loop: Within the loop the function first evaluates `pred()` and exits the loop if the result is `true`.
>    > - Atomically calls `lock.unlock()` and blocks on `*this`.
>    > - When unblocked, calls `lock.lock()` (possibly blocking on the lock).
>    > - The function will unblock when signaled by a call to `notify_one()` or a call to `notify_all()`, by the elapsed time `rel_time` passing (30.2.4), or spuriously.
>    > - If the function exits via an exception, `lock.unlock()` shall be called prior to exiting the function scope.
>    > - The loop terminates when `pred()` returns `true` or when the time duration specified by `rel_time` has elapsed.

Proposed resolution:

Resolved by n3191.