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.5.5.2 [thread.lock.guard], 32.5.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.5.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.5.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.5.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.5.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 mutex lockable 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.5.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.5.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