33 Concurrency support library [thread]

33.6 Mutual exclusion [thread.mutex]

33.6.4 Mutex requirements [thread.mutex.requirements]

33.6.4.3 Timed mutex types [thread.timedmutex.requirements]

33.6.4.3.1 General [thread.timedmutex.requirements.general]

The timed mutex types are the standard library types timed_mutex, recursive_timed_mutex, and shared_timed_mutex.
They meet the requirements set out below.
In this description, m denotes an object of a mutex type, rel_time denotes an object of an instantiation of duration, and abs_time denotes an object of an instantiation of time_point.
[Note 1: 
The timed mutex types meet the Cpp17TimedLockable requirements ([thread.req.lockable.timed]).
— end note]
The expression m.try_lock_for(rel_time) is well-formed and has the following semantics:
Preconditions: If m is of type timed_mutex or shared_timed_mutex, the calling thread does not own the mutex.
Effects: The function attempts to obtain ownership of the mutex within the relative timeout ([thread.req.timing]) specified by rel_time.
If the time specified by rel_time is less than or equal to rel_time.zero(), the function attempts to obtain ownership without blocking (as if by calling try_lock()).
The function returns within the timeout specified by rel_time only if it has obtained ownership of the mutex object.
[Note 2: 
As with try_lock(), there is no guarantee that ownership will be obtained if the lock is available, but implementations are expected to make a strong effort to do so.
— end note]
Synchronization: If try_lock_for() returns true, prior unlock() operations on the same object synchronize with ([intro.multithread]) this operation.
Return type: bool.
Returns: true if ownership was obtained, otherwise false.
Throws: Timeout-related exceptions ([thread.req.timing]).
The expression m.try_lock_until(abs_time) is well-formed and has the following semantics:
Preconditions: If m is of type timed_mutex or shared_timed_mutex, the calling thread does not own the mutex.
Effects: The function attempts to obtain ownership of the mutex.
If abs_time has already passed, the function attempts to obtain ownership without blocking (as if by calling try_lock()).
The function returns before the absolute timeout ([thread.req.timing]) specified by abs_time only if it has obtained ownership of the mutex object.
[Note 3: 
As with try_lock(), there is no guarantee that ownership will be obtained if the lock is available, but implementations are expected to make a strong effort to do so.
— end note]
Synchronization: If try_lock_until() returns true, prior unlock() operations on the same object synchronize with ([intro.multithread]) this operation.
Return type: bool.
Returns: true if ownership was obtained, otherwise false.
Throws: Timeout-related exceptions ([thread.req.timing]).

33.6.4.3.2 Class timed_mutex [thread.timedmutex.class]

namespace std { class timed_mutex { public: timed_mutex(); ~timed_mutex(); timed_mutex(const timed_mutex&) = delete; timed_mutex& operator=(const timed_mutex&) = delete; void lock(); // blocking bool try_lock(); template<class Rep, class Period> bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); template<class Clock, class Duration> bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); void unlock(); using native_handle_type = implementation-defined; // see [thread.req.native] native_handle_type native_handle(); // see [thread.req.native] }; }
The class timed_mutex provides a non-recursive mutex with exclusive ownership semantics.
If one thread owns a timed_mutex object, attempts by another thread to acquire ownership of that object will fail (for try_lock()) or block (for lock(), try_lock_for(), and try_lock_until()) until the owning thread has released ownership with a call to unlock() or the call to try_lock_for() or try_lock_until() times out (having failed to obtain ownership).
The class timed_mutex meets all of the timed mutex requirements ([thread.timedmutex.requirements]).
It is a standard-layout class ([class.prop]).
The behavior of a program is undefined if
  • it destroys a timed_mutex object owned by any thread,
  • a thread that owns a timed_mutex object calls lock(), try_lock(), try_lock_for(), or try_lock_until() on that object, or
  • a thread terminates while owning a timed_mutex object.

33.6.4.3.3 Class recursive_timed_mutex [thread.timedmutex.recursive]

namespace std { class recursive_timed_mutex { public: recursive_timed_mutex(); ~recursive_timed_mutex(); recursive_timed_mutex(const recursive_timed_mutex&) = delete; recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; void lock(); // blocking bool try_lock() noexcept; template<class Rep, class Period> bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); template<class Clock, class Duration> bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); void unlock(); using native_handle_type = implementation-defined; // see [thread.req.native] native_handle_type native_handle(); // see [thread.req.native] }; }
The class recursive_timed_mutex provides a recursive mutex with exclusive ownership semantics.
If one thread owns a recursive_timed_mutex object, attempts by another thread to acquire ownership of that object will fail (for try_lock()) or block (for lock(), try_lock_for(), and try_lock_until()) until the owning thread has completely released ownership or the call to try_lock_for() or try_lock_until() times out (having failed to obtain ownership).
The class recursive_timed_mutex meets all of the timed mutex requirements ([thread.timedmutex.requirements]).
It is a standard-layout class ([class.prop]).
A thread that owns a recursive_timed_mutex object may acquire additional levels of ownership by calling lock(), try_lock(), try_lock_for(), or try_lock_until() on that object.
It is unspecified how many levels of ownership may be acquired by a single thread.
If a thread has already acquired the maximum level of ownership for a recursive_timed_mutex object, additional calls to try_lock(), try_lock_for(), or try_lock_until() fail, and additional calls to lock() throw an exception of type system_error.
A thread shall call unlock() once for each level of ownership acquired by calls to lock(), try_lock(), try_lock_for(), and try_lock_until().
Only when all levels of ownership have been released may ownership of the object be acquired by another thread.
The behavior of a program is undefined if
  • it destroys a recursive_timed_mutex object owned by any thread, or
  • a thread terminates while owning a recursive_timed_mutex object.