Since lock() does not synchronize with a failed subsequent
try_­lock(), the visibility rules are weak enough that little would be
known about the state after a failure, even in the absence of spurious failures.

If one thread owns a mutex object, attempts by another thread to acquire
ownership of that object will fail (for try_­lock()) or block (for
lock()) until the owning thread has released ownership with a call to
unlock().

After a thread A has called unlock(), releasing a mutex, it is possible for another
thread B to lock the same mutex, observe that it is no longer in use, unlock it, and
destroy it, before thread A appears to have returned from its unlock call.

Implementations
are required to handle such scenarios correctly, as long as thread A doesn't access the
mutex after the unlock call returns.

These cases typically occur when a reference-counted object
contains a mutex that is used to protect the reference count.

If one thread owns a recursive_­mutex object, attempts by another
thread to acquire ownership of that object will fail (for try_­lock()) or block
(for lock()) until the first thread has completely released ownership.

A thread that owns a recursive_­mutex object may acquire additional levels of
ownership by calling lock() or try_­lock() 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_­mutex
object, additional calls to try_­lock() shall fail, and additional calls to
lock() shall throw an exception of type system_­error.

A thread
shall call unlock() once for each level of ownership acquired by calls to
lock() and try_­lock().

Only when all levels of ownership have been
released may ownership be acquired by another thread.

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).

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).

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() shall fail, and additional
calls to lock() shall 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.

But no
execution agent shall hold a shared lock while another execution agent holds an
exclusive lock on the same shared mutex type, and vice-versa.

The maximum
number of execution agents which can share a shared lock on a single shared
mutex type is unspecified, but shall be at least 10000.

If more than the
maximum number of execution agents attempt to obtain a shared lock, the
excess execution agents shall block until the number of shared locks are
reduced below the maximum amount by other execution agents releasing their
shared lock.

The behavior of a program is undefined if the contained pointer
pm is not null and the lockable object pointed
to by pm does not exist for the entire remaining
lifetime ([basic.life]) of the unique_­lock object.

The behavior of a program
is undefined if the contained pointer pm is not null and the lockable
object pointed to by pm does not exist for the entire remaining
lifetime ([basic.life]) of the shared_­lock object.

Effects: Calls try_­lock() for each argument in order beginning with the
first until all arguments have been processed or a call to try_­lock() fails,
either by returning false or by throwing an exception.

If a call to
try_­lock() fails, unlock() is called for all prior arguments
with no further calls to try_­lock().

An exceptional execution shall propagate the exception to the caller of
call_­once.

Among all executions of call_­once for any given
once_­flag: at most one shall be a returning execution; if there is a
returning execution, it shall be the last active execution; and there are
passive executions only if there is a returning execution.

Synchronization: For any given once_­flag: all active executions occur in a total
order; completion of an active execution synchronizes with
the start of the next one in this total order; and the returning execution
synchronizes with the return from all passive executions.