+1

> That's fine, but that's not what "Lockable" means. If you're using
RAII-based scoped locks, that means you *don't* want to do what you're
describing. Scoped locking doesn't make sense if someone outside of
that scope can unlock it.

Indeed, the normative reference of _BasicLockable_ requirement is is clear, the call `m.unlock()` requires the calling execution agent to hold a lock on `m`.  See

https://en.cppreference.com/w/cpp/named_req/BasicLockable

Julien V.


On February 23, 2023 9:27:04 a.m. EST, Jason McKesson via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Thu, Feb 23, 2023 at 3:39 AM Frederick Virchanza Gotham via
Std-Proposals <std-proposals@lists.isocpp.org> wrote:

On Thu, Feb 23, 2023 at 1:30 AM Jason McKesson via Std-Proposals
<std-proposals@lists.isocpp.org> wrote:

A Lockable type has a built-in assumption: if your thread locks it,
only your thread can unlike it. This allows a scoped lock type like
`unique_lock` to offer the guarantee that if your thread's stack holds
that lock, then only the termination of that scope can unlock it.

A binary_semaphore offers *no such guarantee*. If you can access a
binary_semaphore object, you can *unlock it*. Even if some other
thread locked it, you can unlock it for them. It's not a mutex. In
fact, not being a mutex is the *point of the type*.

This is also why `atomic`s are not, and should not be, Lockable. They
don't participate in the fundamental assumption of ownership of locks.


Sometimes I want a mutex that can be unlocked by a thread other than
the one that locked it.

That's fine, but that's not what "Lockable" means. If you're using
RAII-based scoped locks, that means you *don't* want to do what you're
describing. Scoped locking doesn't make sense if someone outside of
that scope can unlock it.