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.
try_lock
contradictionSection: 32.6.6 [thread.lock.algorithm] Status: C++11 Submitter: Chris Fairles Opened: 2009-02-14 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [thread.lock.algorithm].
View all issues with C++11 status.
Discussion:
In 32.6.6 [thread.lock.algorithm], the generic try_lock
effects (p2) say that a failed
try_lock
is when it either returns false
or throws an exception. In
the event a call to try_lock
does fail, by either returning false
or
throwing an exception, it states that unlock
shall be called for all
prior arguments. Then the returns clause (p3) goes on to state
in a note that after returning, either all locks are locked or none
will be. So what happens if multiple locks fail on try_lock
?
Example:
#include <mutex> int main() { std::mutex m0, m1, m2; std::unique_lock<std::mutex> l0(m0, std::defer_lock); std::unique_lock<std::mutex> l1(m1); //throws on try_lock std::unique_lock<std::mutex> l2(m2); //throws on try_lock int result = std::try_lock(l0, l1, l2); assert( !l0.owns_lock() ); assert( l1.owns_lock() ); //?? assert( l2.owns_lock() ); //?? }
The first lock's try_lock
succeeded but, being a prior argument to a
lock whose try_lock
failed, it gets unlocked as per the effects clause
of 32.6.6 [thread.lock.algorithm]. However, 2 locks remain locked in this case but the return
clause states that either all arguments shall be locked or none will
be. This seems to be a contradiction unless the intent is for
implementations to make an effort to unlock not only prior arguments,
but the one that failed and those that come after as well. Shouldn't
the note only apply to the arguments that were successfully locked?
Further discussion and possible resolutions in c++std-lib-23049.
[ Summit: ]
Move to review. Agree with proposed resolution.
[ Batavia (2009-05): ]
We agree with the proposed resolution. Move to Tentatively Ready.
Proposed resolution:
Change 32.6.6 [thread.lock.algorithm], p2:
-2- Effects: Calls
try_lock()
for each argument in order beginning with the first until all arguments have been processed or a call totry_lock()
fails, either by returningfalse
or by throwing an exception. If a call totry_lock()
fails,unlock()
shall be called for all prior arguments and there shall be no further calls totry_lock()
.
Delete the note from 32.6.6 [thread.lock.algorithm], p3
-3- Returns: -1 if all calls to
try_lock()
returnedtrue
, otherwise a 0-based index value that indicates the argument for whichtry_lock()
returnedfalse
.[Note: On return, either all arguments will be locked or none will be locked. -- end note]