Date
2010-10-21.18:28:33
Message id
4085

Content

Proposed resolution:

Change [thread.condition.condvar], p21-22:

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

Precondition: lock is locked by the calling thread, and either

  • no other thread is waiting on this condition_variable object or
  • lock.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting threads (via wait, wait_for or wait_until).

21 Effects:

wait_until(lock, chrono::monotonic_clock::now() + rel_time)
  • Atomically calls lock.unlock() and blocks on *this.
  • When unblocked, calls lock.lock() (possibly blocking on the lock) and returns.
  • The function will unblock when signaled by a call to notify_one(), a call to notify_all(), by the elapsed time rel_time passing ([thread.req.timing]), or spuriously.
  • If the function exits via an exception, lock.unlock() shall be called prior to exiting the function scope.

Postcondition: lock is locked by the calling thread.

22 Returns: false if the call is returning because the time duration specified by rel_time has elapsed, otherwise true.

This part of the wording may conflict with 857 in detail, but does not do so in spirit. If both issues are accepted, there is a logical merge.

Throws: std::system_error when the effects or postcondition cannot be achieved.

Error conditions:

  • operation_not_permitted -- if the thread does not own the lock.
  • equivalent error condition from lock.lock() or lock.unlock().

Change [thread.condition.condvar], p26-p29:

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

Precondition: lock is locked by the calling thread, and either

  • no other thread is waiting on this condition_variable object or
  • lock.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting threads (via wait, wait_for or wait_until).

26 Effects:

wait_until(lock, chrono::monotonic_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 of pred() 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(), a call to notify_all(), by the elapsed time rel_time passing (30.1.4 [thread.req.timing]), 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.

27 [Note: There is no blocking if pred() is initially true, even if the timeout has already expired. -- end note]

Postcondition: lock is locked by the calling thread.

28 Returns: pred()

29 [Note: The returned value indicates whether the predicate evaluates to true regardless of whether the timeout was triggered. -- end note]

Throws: std::system_error when the effects or postcondition cannot be achieved.

Error conditions:

  • operation_not_permitted -- if the thread does not own the lock.
  • equivalent error condition from lock.lock() or lock.unlock().

Change [thread.condition.condvarany], p18-19:

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

18 Effects:

wait_until(lock, chrono::monotonic_clock::now() + rel_time)
  • Atomically calls lock.unlock() and blocks on *this.
  • When unblocked, calls lock.lock() (possibly blocking on the lock) and returns.
  • The function will unblock when signaled by a call to notify_one(), a call to notify_all(), by the elapsed time rel_time passing ([thread.req.timing]), or spuriously.
  • If the function exits via an exception, lock.unlock() shall be called prior to exiting the function scope.

Postcondition: lock is locked by the calling thread.

19 Returns: false if the call is returning because the time duration specified by rel_time has elapsed, otherwise true.

Throws: std::system_error when the returned value, effects, or postcondition cannot be achieved.

Error conditions:

  • equivalent error condition from lock.lock() or lock.unlock().

Change [thread.condition.condvarany], p23-p26:

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

Precondition: lock is locked by the calling thread, and either

  • no other thread is waiting on this condition_variable object or
  • lock.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting threads (via wait, wait_for or wait_until).

23 Effects:

wait_until(lock, chrono::monotonic_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 of pred() 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(), a call to notify_all(), by the elapsed time rel_time passing (30.1.4 [thread.req.timing]), 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.

24 [Note: There is no blocking if pred() is initially true, even if the timeout has already expired. -- end note]

Postcondition: lock is locked by the calling thread.

25 Returns: pred()

26 [Note: The returned value indicates whether the predicate evaluates to true regardless of whether the timeout was triggered. -- end note]

Throws: std::system_error when the effects or postcondition cannot be achieved.

Error conditions:

  • operation_not_permitted -- if the thread does not own the lock.
  • equivalent error condition from lock.lock() or lock.unlock().