32 Thread support library [thread]

32.2 Requirements [thread.req]

32.2.5 Requirements for Cpp17Lockable types [thread.req.lockable]

32.2.5.1 In general [thread.req.lockable.general]

An execution agent is an entity such as a thread that may perform work in parallel with other execution agents.
[Note 1:
Implementations or users can introduce other kinds of agents such as processes or thread-pool tasks.
— end note]
The calling agent is determined by context, e.g., the calling thread that contains the call, and so on.
[Note 2:
Some lockable objects are “agent oblivious” in that they work for any execution agent model because they do not determine or store the agent's ID (e.g., an ordinary spin lock).
— end note]
The standard library templates unique_­lock ([thread.lock.unique]), shared_­lock ([thread.lock.shared]), scoped_­lock ([thread.lock.scoped]), lock_­guard ([thread.lock.guard]), lock, try_­lock ([thread.lock.algorithm]), and condition_­variable_­any ([thread.condition.condvarany]) all operate on user-supplied lockable objects.
The Cpp17BasicLockable requirements, the Cpp17Lockable requirements, and the Cpp17TimedLockable requirements list the requirements imposed by these library types in order to acquire or release ownership of a lock by a given execution agent.
[Note 3:
The nature of any lock ownership and any synchronization it entails are not part of these requirements.
— end note]

32.2.5.2 Cpp17BasicLockable requirements [thread.req.lockable.basic]

A type L meets the Cpp17BasicLockable requirements if the following expressions are well-formed and have the specified semantics (m denotes a value of type L).
m.lock()
Effects: Blocks until a lock can be acquired for the current execution agent.
If an exception is thrown then a lock shall not have been acquired for the current execution agent.
m.unlock()
Preconditions: The current execution agent holds a lock on m.
Effects: Releases a lock on m held by the current execution agent.
Throws: Nothing.

32.2.5.3 Cpp17Lockable requirements [thread.req.lockable.req]

A type L meets the Cpp17Lockable requirements if it meets the Cpp17BasicLockable requirements and the following expressions are well-formed and have the specified semantics (m denotes a value of type L).
m.try_lock()
Effects: Attempts to acquire a lock for the current execution agent without blocking.
If an exception is thrown then a lock shall not have been acquired for the current execution agent.
Return type: bool.
Returns: true if the lock was acquired, otherwise false.

32.2.5.4 Cpp17TimedLockable requirements [thread.req.lockable.timed]

A type L meets the Cpp17TimedLockable requirements if it meets the Cpp17Lockable requirements and the following expressions are well-formed and have the specified semantics (m denotes a value of type L, rel_­time denotes a value of an instantiation of duration, and abs_­time denotes a value of an instantiation of time_­point).
m.try_lock_for(rel_time)
Effects: Attempts to acquire a lock for the current execution agent within the relative timeout ([thread.req.timing]) specified by rel_­time.
The function will not return within the timeout specified by rel_­time unless it has obtained a lock on m for the current execution agent.
If an exception is thrown then a lock has not been acquired for the current execution agent.
Return type: bool.
Returns: true if the lock was acquired, otherwise false.
m.try_lock_until(abs_time)
Effects: Attempts to acquire a lock for the current execution agent before the absolute timeout ([thread.req.timing]) specified by abs_­time.
The function will not return before the timeout specified by abs_­time unless it has obtained a lock on m for the current execution agent.
If an exception is thrown then a lock has not been acquired for the current execution agent.
Return type: bool.
Returns: true if the lock was acquired, otherwise false.