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.

2023. Incorrect requirements for lock_guard and unique_lock

Section: 32.6.5.2 [thread.lock.guard], 32.6.5.4 [thread.lock.unique] Status: Resolved Submitter: Daniel Krügler Opened: 2010-12-08 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [thread.lock.guard].

View all issues with Resolved status.

Discussion:

There are two different *Lockable requirements imposed on template arguments of the class template lock_guard as of 32.6.5.2 [thread.lock.guard] p. 1+2:

1 [..] The supplied Mutex type shall meet the BasicLockable requirements (30.2.5.2).

2 The supplied Mutex type shall meet the Lockable requirements (30.2.5.3).

The Lockable requirements include the availability of a member function try_lock(), but there is no operational semantics in the specification of lock_guard that would rely on such a function. It seems to me that paragraph 2 should be removed.

Similarly, 32.6.5.4 [thread.lock.unique] p. 1+2 refer to exactly the same two requirements. In this case it seems as if the intention was that the template arguement Mutex should always provide the try_lock() member function, because several member functions of unique_lock (unique_lock(mutex_type& m, try_to_lock_t) or bool try_lock()) take advantage of such a function without adding extra requirements for this. It seems that the requirement subset BasicLockable should be removed.

I searched for further possible misusages of the *Lockable requirements, but could not find any more.

[2011-02-23]

Howard suggests an alternative approach in regard to unique_lock: The current minimum requirements on its template argument should better be reduced to BasicLockable instead of the current Lockable, including ammending member-wise constraints where required. This suggestions was supported by Anthony, Daniel, and Pablo.

Daniel drafts wording that follows this separation strategy.

[2011-02-24 Reflector discussion]

Moved to Tentatively Ready after 5 votes.

The suggested wording changes are against the working draft N3242.

  1. Remove 32.6.5.2 [thread.lock.guard] p. 2 completely:

    2 The supplied Mutex type shall meet the Lockable requirements (30.2.5.3).

  2. Change 32.6.5.4 [thread.lock.unique] p. 1-3 as indicated. The intend is to make BasicLockable the fundamental requirement for unique_lock. We also update the note to reflect these changes and synchronize one remaining reference of 'mutex' by the proper term 'lockable object' in sync to the wording changes of lock_guard:

    1 [..] The behavior of a program is undefined if the contained pointer pm is not null and the mutexlockable object pointed to by pm does not exist for the entire remaining lifetime (3.8) of the unique_lock object. The supplied Mutex type shall meet the BasicLockable requirements (30.2.5.2). [Editor's note: BasicLockable is redundant, since the following additional paragraph requires Lockable.]

    2 The supplied Mutex type shall meet the Lockable requirements (30.2.5.3).

    3 [ Note: unique_lock<Mutex> meets the BasicLockable requirements. If Mutex meets the Lockable requirements ([thread.req.lockable.req]), unique_lock<Mutex> also meets the Lockable requirements and if Mutex meets the TimedLockable requirements (30.2.5.4), unique_lock<Mutex> also meets the TimedLockable requirements. — end note ]

  3. Modify 32.6.5.4.2 [thread.lock.unique.cons] to add the now necessary member-wise additional constraints for Lockable:

    unique_lock(mutex_type& m, try_to_lock_t) noexcept;
    

    8 Requires: The supplied Mutex type shall meet the Lockable requirements ([thread.req.lockable.req]). If mutex_type is not a recursive mutex the calling thread does not own the mutex.

    9 Effects: Constructs an object of type unique_lock and calls m.try_lock().

  4. Modify 32.6.5.4.3 [thread.lock.unique.locking] to add the now necessary member-wise additional constraints for Lockable:

    bool try_lock();
    

    ? Requires: The supplied Mutex type shall meet the Lockable requirements ([thread.req.lockable.req]).

    4 Effects: pm->try_lock()

Proposed resolution:

Resolved 2011-03 Madrid meeting by paper N3278