Does unique_lock fulfill BasicLockable only by fiat?

30 views
Skip to first unread message

Paul "TBBle" Hampson

unread,
Aug 12, 2017, 2:41:38 PM8/12/17
to ISO C++ Standard - Discussion
Prompted by a slightly-old Stack Overflow answer about putting unique_lock in a lock_guard, it seems that std::unique_lock::unlock fails to meet the BasicLockable requirements, even though it has a Note declaring that it does.

The apparent defect is:

[thread.lock.unique.locking]/25 states that std::unique_lock::unlock "Throws: system_error when an exception is required".

[thread.req.lockable.basic]/5 states that for a type to meet BasicLockable its unlock() member function "Throws: Nothing".

I had a poke around, and couldn't find any other reference to this apparent conflict.

Perhaps this is okay, in that looking slightly wider, std::unique_lock::unlock's only listed error condition is "if on entry owns is false", while BasicLockable's unlock() member function "Requires: The current execution agent shall hold a lock on m.". 

If we can equate std::unique_lock::owns with "the current execution agent holds a lock on the std::unique_lock instance" then the standard is fine: So as long as you meet the BasicLockable Requires clause to call unlock(), then unique_lock::unlock won't violate the BasicLockable Throws clause.

Is this latter approach the right way to read that?

As a nit-pick, the term "hold a lock" is applied in only a few places, while "own" and "ownership" appear the more common terms, applied to both locks and mutexes. In one place, it's "hold a shared lock ownership", discovering the best of both worlds.

Thiago Macieira

unread,
Aug 12, 2017, 3:47:08 PM8/12/17
to std-dis...@isocpp.org
On sábado, 12 de agosto de 2017 11:41:38 PDT Paul "TBBle" Hampson wrote:
> Perhaps this is okay, in that looking slightly wider,
> std::unique_lock::unlock's only listed error condition is "if on entry owns
> is false", while BasicLockable's unlock() member function "*Requires:* The
> current execution agent shall hold a lock on m.".
>
> If we can equate std::unique_lock::owns with "the current execution agent
> holds a lock on the std::unique_lock instance" then the standard is fine:
> So as long as you meet the BasicLockable *Requires* clause to call unlock(),
> then unique_lock::unlock won't violate the BasicLockable *Throws* clause.
>
> Is this latter approach the right way to read that?

I would read it like that. If you use the API correctly, it won't throw.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center

Reply all
Reply to author
Forward
0 new messages