This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++11 status.
lock() postcondition can not be generally achievedSection: 32.7 [thread.condition] Status: C++11 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 C++11 status.
Discussion:
Addresses CH-30
If lock.lock() throws an exception, the postcondition can not be generally achieved.
[ Resolution proposed by ballot comment: ]
Either state that the postcondition might not be achieved, depending on the error condition, or state that
terminate()is called in this case.
[ 2010-08-13 Peter Sommerlad comments and provides wording ]
32.7.4 [thread.condition.condvar], 32.7.5 [thread.condition.condvarany]
p. 13, last bullet, and corresponding paragraphs in all wait functions Problem:
Condition variable wait might fail, because the lock cannot be acquired when notified. CH-30 says: "If lock.lock() throws an exception, the postcondition can not be generally achieved." CH-30 proposes: "Either state that the postcondition might not be achieved, depending on the error condition, or state that terminate() is called in this case." The discussion in Rapperswil concluded that callingterminate()might be too drastic in this case and a corresponding exception should be thrown/passed on and one should use a lock type that allows querying its status, whichunique_lockallows forstd::condition_variableWe also had some additional observations while discussing in Rapperswil:
- in 32.7.4 [thread.condition.condvar]
waitwith predicate andwait_untilwith predicate lack the precondition, postcondition and Error conditions sections. the lack of the precondition would allow to callpred()without holding the lock.- in 32.7.4 [thread.condition.condvar]
wait_untilandwait_forand 32.7.5 [thread.condition.condvarany]wait_forstill specify an error condition for a violated precondition. This should be removed.and add the following proposed solution:
[2011-02-27: Daniel adapts numbering to n3225]
Proposed resolution:
void wait(unique_lock<mutex>& lock);
[..]9 Requires:
lock.owns_lock()istrueandlock.mutex()is locked by the calling thread, and either
- no other thread is waiting on this
condition_variableobject orlock.mutex()returns the same value for each of thelockarguments supplied by all concurrently waiting (viawaitortimed_wait) threads.
[..]11 Postcondition:
lock.owns_lock()istrueandlock.mutex()is locked by the calling thread.
template <class Predicate> void wait(unique_lock<mutex>& lock, Predicate pred);
?? Requires:
lock.owns_lock()istrueandlock.mutex()is locked by the calling thread, and either
- no other thread is waiting on this
condition_variableobject orlock.mutex()returns the same value for each of thelockarguments supplied by all concurrently waiting (viawaitortimed_wait) threads.
14 Effects:
while (!pred()) wait(lock);
?? Postcondition:
lock.owns_lock()istrueandlock.mutex()is locked by the calling thread.
?? Throws:
std::system_errorwhen an exception is required (30.2.2).
?? Error conditions:
- equivalent error condition from
lock.lock()orlock.unlock().
template <class Clock, class Duration> cv_status wait_until(unique_lock<mutex>& lock, const chrono::time_point<Clock, Duration>& abs_time);
15 Requires:
lock.owns_lock()istrueandlock.mutex()is locked by the calling thread, and either
- no other thread is waiting on this
condition_variableobject orlock.mutex()returns the same value for each of thelockarguments supplied by all concurrently waiting (viawait,wait_for, orwait_until) threads.
[..]
[..]17 Postcondition:
lock.owns_lock()istrueandlock.mutex()is locked by the calling thread.
20 Error conditions:
operation_not_permitted— if the thread does not own the lock.- equivalent error condition from
lock.lock()orlock.unlock().
template <class Rep, class Period> cv_status wait_for(unique_lock<mutex>& lock, const chrono::duration<Rep, Period>& rel_time);
21 Requires:
lock.owns_lock()istrueandlock.mutex()is locked by the calling thread, and either
- no other thread is waiting on this
condition_variableobject orlock.mutex()returns the same value for each of thelockarguments supplied by all concurrently waiting (viawait,wait_for, orwait_until) threads.
[..]
[..]24 Postcondition:
lock.owns_lock()istrueandlock.mutex()is locked by the calling thread.
26 Error conditions:
operation_not_permitted— if the thread does not own the lock.- equivalent error condition from
lock.lock()orlock.unlock().
template <class Clock, class Duration, class Predicate>
bool wait_until(unique_lock<mutex>& lock,
const chrono::time_point<Clock, Duration>& abs_time,
Predicate pred);
?? Requires:
lock.owns_lock()istrueandlock.mutex()is locked by the calling thread, and either
- no other thread is waiting on this
condition_variableobject orlock.mutex()returns the same value for each of thelockarguments supplied by all concurrently waiting (viawaitortimed_wait) threads.
27 Effects:
while (!pred()) if (wait_until(lock, abs_time) == cv_status::timeout) return pred(); return true;
28 Returns:
pred()
?? Postcondition:
lock.owns_lock()istrueandlock.mutex()is locked by the calling thread.
29 [ Note: The returned value indicates whether the predicate evaluates to true regardless of whether the timeout was triggered. — end note ]
?? Throws:
std::system_errorwhen an exception is required (30.2.2).
?? Error conditions:
- equivalent error condition from
lock.lock()orlock.unlock().
template <class Rep, class Period, class Predicate>
bool wait_for(unique_lock<mutex>& lock,
const chrono::duration<Rep, Period>& rel_time,
Predicate pred);
30 Requires:
lock.owns_lock()istrueandlock.mutex()is locked by the calling thread, and either
- no other thread is waiting on this
condition_variableobject orlock.mutex()returns the same value for each of thelockarguments supplied by all concurrently waiting (viawait,wait_for, orwait_until) threads.
[..]
33 Postcondition:
lock.owns_lock()istrueandlock.mutex()is locked by the calling thread.
[..]
37 Error conditions:
operation_not_permitted— if the thread does not own the lock.- equivalent error condition from
lock.lock()orlock.unlock().
template <class Lock, class Predicate> void wait(Lock& lock, Predicate pred);
[Note: if any of the wait functions exits with an exception it is indeterminate if the
Lockis held. One can use aLocktype that allows to query that, such as theunique_lockwrapper. — end note]
11 Effects:
while (!pred()) wait(lock);
[..]
31 Error conditions:
operation_not_permitted— if the thread does not own the lock.- equivalent error condition from
lock.lock()orlock.unlock().