carb::thread::recursive_shared_mutex

Defined in carb/thread/RecursiveSharedMutex.h

class recursive_shared_mutex : private carb::thread::shared_mutex

A recursive shared mutex.

Similar to std::shared_mutex or carb::thread::shared_mutex, but can be used recursively.

This primitive supports lock conversion: If a thread already holds one or more shared locks and attempts to take an exclusive lock, the shared locks are released and the same number of exclusive locks are added. However, this is not done atomically.

A single thread-local storage entry is used to track the list of

recursive_shared_mutex objects that a thread has locked and their recursive lock depth. However, as this is a header-only class, all modules that use this class will allocate their own thread-local storage entry.

See also

recursive_shared_mutex::lock() for more info.

Public Functions

inline constexpr recursive_shared_mutex()

Constructor.

~recursive_shared_mutex() = default

Destructor.

Debug builds assert that the mutex is not busy (locked) when destroyed.

inline void lock()

Blocks until an exclusive lock can be obtained.

When this function returns, the calling thread exclusively owns the mutex. At some later point the calling thread will need to call unlock() to release the exclusive lock.

Note

If the calling thread has taken shared locks on this mutex, all of the shared locks are converted to exclusive locks.

Warning

If existing shared locks must be converted to exclusive locks, the mutex must convert these shared locks to exclusive locks. In order to do this, it must first release all shared locks which potentially allows another thread to gain exclusive access and modify the shared resource. Therefore, any time an exclusive lock is taken, assume that the shared resource may have been modified, even if the calling thread held a shared lock before.

inline bool try_lock()

Attempts to immediately take an exclusive lock, but will not block if one cannot be obtained.

Note

If the calling thread has taken shared locks on this mutex, false is returned and no attempt to convert the locks is made. If the calling thread already has an exclusive lock on this mutex, true is always returned.

Returns

true if an exclusive lock could be obtained, and at some later point unlock() will need to be called to release the lock. If an exclusive lock could not be obtained immediately, false is returned.

inline void unlock()

Releases either a single shared or exclusive lock on this mutex.

Synonymous with unlock_shared().

Note

If the calling thread has recursively locked this mutex, unlock() will need to be called symmetrically for each call to a successful locking function.

Warning

std::terminate() will be called if the calling thread does not have the mutex locked.

inline void lock_shared()

Blocks until a shared lock can be obtained.

When this function returns, the calling thread has obtained a shared lock on the resources protected by the mutex. At some later point the calling thread must call unlock_shared() to release the shared lock.

Note

If the calling thread already owns an exclusive lock, then calling lock_shared() will actually increase the exclusive lock count.

inline bool try_lock_shared()

Attempts to immediately take a shared lock, but will not block if one cannot be obtained.

Note

If the calling thread already owns an exclusive lock, then calling try_lock_shared() will always return true and will actually increase the exclusive lock count.

Returns

true if a shared lock could be obtained, and at some later point unlock_shared() will need to be called to release the lock. If a shared lock could not be obtained immediately, false is returned.

inline void unlock_shared()

Releases either a single shared or exclusive lock on this mutex.

Synonymous with unlock().

Note

If the calling thread has recursively locked this mutex, unlock() or unlock_shared() will need to be called symmetrically for each call to a successful locking function.

Warning

std::terminate() will be called if calling thread does not have the mutex locked.

inline bool owns_lock() const

Returns true if the calling thread owns the lock.

Note

Use owns_lock_shared() or owns_lock_exclusive() for a more specific check.

Returns

true if the calling thread owns the lock, either exclusively or shared; false otherwise.

inline bool owns_lock_shared() const

Returns true if the calling thread owns a shared lock.

Returns

true if the calling thread owns a shared lock; false otherwise.

inline bool owns_lock_exclusive() const

Returns true if the calling thread owns an exclusive lock.

Returns

true if the calling thread owns an exclusive lock; false otherwise.