13#include <condition_variable>
46template <
typename MutexType>
47void EnterCritical(
const char* pszName,
const char* pszFile,
int nLine, MutexType*
cs,
bool fTry =
false);
49void CheckLastCritical(
void*
cs, std::string& lockname,
const char* guardname,
const char* file,
int line);
50template <
typename MutexType>
52template <
typename MutexType>
62extern bool g_debug_lockorder_abort;
64template <
typename MutexType>
65inline void EnterCritical(
const char* pszName,
const char* pszFile,
int nLine, MutexType*
cs,
bool fTry =
false) {}
67inline void CheckLastCritical(
void*
cs, std::string& lockname,
const char* guardname,
const char* file,
int line) {}
68template <
typename MutexType>
70template <
typename MutexType>
80#ifdef DEBUG_LOCKCONTENTION
82template <
typename LockType>
83void ContendedLock(std::string_view
name, std::string_view file,
int nLine, LockType& lock);
90template <
typename PARENT>
110 return PARENT::try_lock();
142#define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs)
147#define AssertLockNotHeld(cs) AssertLockNotHeldInline(#cs, __FILE__, __LINE__, &cs)
150template <
typename MutexType>
154 using Base =
typename MutexType::unique_lock;
156 void Enter(
const char* pszName,
const char* pszFile,
int nLine)
159#ifdef DEBUG_LOCKCONTENTION
160 if (!Base::try_lock()) {
161 ContendedLock(pszName, pszFile, nLine,
static_cast<Base&
>(*
this));
168 bool TryEnter(
const char* pszName,
const char* pszFile,
int nLine)
171 if (Base::try_lock()) {
182 TryEnter(pszName, pszFile, nLine);
184 Enter(pszName, pszFile, nLine);
189 if (!pmutexIn)
return;
191 *
static_cast<Base*
>(
this) =
Base(*pmutexIn, std::defer_lock);
193 TryEnter(pszName, pszFile, nLine);
195 Enter(pszName, pszFile, nLine);
200 if (Base::owns_lock())
206 return Base::owns_lock();
221 assert(std::addressof(mutex) == lock.mutex());
231 EnterCritical(lockname.c_str(), file.c_str(), line, lock.mutex());
252#define REVERSE_LOCK(g, cs) typename std::decay<decltype(g)>::type::reverse_lock UNIQUE_NAME(revlock)(g, cs, #cs, __FILE__, __LINE__)
261template <
typename MutexType>
263template <
typename MutexType>
266#define LOCK(cs) UniqueLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__)
267#define LOCK2(cs1, cs2) \
268 UniqueLock criticalblock1(MaybeCheckNotHeld(cs1), #cs1, __FILE__, __LINE__); \
269 UniqueLock criticalblock2(MaybeCheckNotHeld(cs2), #cs2, __FILE__, __LINE__)
270#define LOCK_ARGS(cs) MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__
271#define TRY_LOCK(cs, name) UniqueLock name(LOCK_ARGS(cs), true)
272#define WAIT_LOCK(cs, name) UniqueLock name(LOCK_ARGS(cs))
297#define WITH_LOCK(cs, code) (MaybeCheckNotHeld(cs), [&]() -> decltype(auto) { LOCK(cs); code; }())
Template mixin that adds -Wthread-safety locking annotations and lock order checking to a subset of t...
std::unique_lock< PARENT > unique_lock
bool try_lock() EXCLUSIVE_TRYLOCK_FUNCTION(true)
void unlock() UNLOCK_FUNCTION()
void lock() EXCLUSIVE_LOCK_FUNCTION()
(Un)serialize a number as raw byte or 2 hexadecimal chars.
Different type to mark Mutex at global scope.
An RAII-style reverse lock.
~reverse_lock() UNLOCK_FUNCTION()
reverse_lock(UniqueLock &_lock, const MutexType &mutex, const char *_guardname, const char *_file, int _line) UNLOCK_FUNCTION(mutex)
reverse_lock(reverse_lock const &)
reverse_lock & operator=(reverse_lock const &)
Wrapper around std::unique_lock style lock for MutexType.
~UniqueLock() UNLOCK_FUNCTION()
bool TryEnter(const char *pszName, const char *pszFile, int nLine)
void Enter(const char *pszName, const char *pszFile, int nLine)
UniqueLock(MutexType &mutexIn, const char *pszName, const char *pszFile, int nLine, bool fTry=false) EXCLUSIVE_LOCK_FUNCTION(mutexIn)
UniqueLock(MutexType *pmutexIn, const char *pszName, const char *pszFile, int nLine, bool fTry=false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn)
void AssertLockHeldInternal(const char *pszName, const char *pszFile, int nLine, MutexType *cs) EXCLUSIVE_LOCKS_REQUIRED(cs)
void AssertLockNotHeldInline(const char *name, const char *file, int line, Mutex *cs) EXCLUSIVE_LOCKS_REQUIRED(!cs)
void EnterCritical(const char *pszName, const char *pszFile, int nLine, MutexType *cs, bool fTry=false)
void DeleteLock(void *cs)
void CheckLastCritical(void *cs, std::string &lockname, const char *guardname, const char *file, int line)
Mutex & MaybeCheckNotHeld(Mutex &cs) EXCLUSIVE_LOCKS_REQUIRED(!cs) LOCK_RETURNED(cs)
void AssertLockNotHeldInternal(const char *pszName, const char *pszFile, int nLine, MutexType *cs) LOCKS_EXCLUDED(cs)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
#define EXCLUSIVE_TRYLOCK_FUNCTION(...)
#define LOCKS_EXCLUDED(...)
#define EXCLUSIVE_LOCK_FUNCTION(...)
#define UNLOCK_FUNCTION(...)