12 #include <condition_variable> 50 #ifdef DEBUG_LOCKORDER 51 template <
typename MutexType>
52 void EnterCritical(
const char* pszName,
const char* pszFile,
int nLine, MutexType*
cs,
bool fTry =
false);
54 void CheckLastCritical(
void*
cs, std::string& lockname,
const char* guardname,
const char* file,
int line);
55 std::string LocksHeld();
56 template <
typename MutexType>
58 template <
typename MutexType>
68 extern bool g_debug_lockorder_abort;
70 template <
typename MutexType>
71 inline void EnterCritical(
const char* pszName,
const char* pszFile,
int nLine, MutexType*
cs,
bool fTry =
false) {}
73 inline void CheckLastCritical(
void*
cs, std::string& lockname,
const char* guardname,
const char* file,
int line) {}
74 template <
typename MutexType>
76 template <
typename MutexType>
81 #define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs) 82 #define AssertLockNotHeld(cs) AssertLockNotHeldInternal(#cs, __FILE__, __LINE__, &cs) 88 template <
typename PARENT>
108 return PARENT::try_lock();
129 #ifdef DEBUG_LOCKCONTENTION 130 void PrintLockContention(
const char* pszName,
const char* pszFile,
int nLine);
134 template <
typename Mutex,
typename Base =
typename Mutex::UniqueLock>
138 void Enter(
const char* pszName,
const char* pszFile,
int nLine)
141 #ifdef DEBUG_LOCKCONTENTION 142 if (!Base::try_lock()) {
143 PrintLockContention(pszName, pszFile, nLine);
146 #ifdef DEBUG_LOCKCONTENTION 151 bool TryEnter(
const char* pszName,
const char* pszFile,
int nLine)
155 if (!Base::owns_lock())
157 return Base::owns_lock();
164 TryEnter(pszName, pszFile, nLine);
166 Enter(pszName, pszFile, nLine);
171 if (!pmutexIn)
return;
173 *
static_cast<Base*
>(
this) = Base(*pmutexIn, std::defer_lock);
175 TryEnter(pszName, pszFile, nLine);
177 Enter(pszName, pszFile, nLine);
182 if (Base::owns_lock())
188 return Base::owns_lock();
201 explicit reverse_lock(
UniqueLock& _lock,
const char* _guardname,
const char* _file,
int _line) : lock(_lock), file(_file), line(_line) {
210 EnterCritical(lockname.c_str(), file.c_str(), line, lock.mutex());
227 #define REVERSE_LOCK(g) typename std::decay<decltype(g)>::type::reverse_lock PASTE2(revlock, __COUNTER__)(g, #g, __FILE__, __LINE__) 229 template<
typename MutexArg>
232 #define LOCK(cs) DebugLock<decltype(cs)> PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) 233 #define LOCK2(cs1, cs2) \ 234 DebugLock<decltype(cs1)> criticalblock1(cs1, #cs1, __FILE__, __LINE__); \ 235 DebugLock<decltype(cs2)> criticalblock2(cs2, #cs2, __FILE__, __LINE__); 236 #define TRY_LOCK(cs, name) DebugLock<decltype(cs)> name(cs, #cs, __FILE__, __LINE__, true) 237 #define WAIT_LOCK(cs, name) DebugLock<decltype(cs)> name(cs, #cs, __FILE__, __LINE__) 239 #define ENTER_CRITICAL_SECTION(cs) \ 241 EnterCritical(#cs, __FILE__, __LINE__, &cs); \ 245 #define LEAVE_CRITICAL_SECTION(cs) \ 247 std::string lockname; \ 248 CheckLastCritical((void*)(&cs), lockname, #cs, __FILE__, __LINE__); \ 276 #define WITH_LOCK(cs, code) [&]() -> decltype(auto) { LOCK(cs); code; }() 290 std::unique_lock<std::mutex> lock(
mutex);
297 std::lock_guard<std::mutex> lock(
mutex);
307 std::lock_guard<std::mutex> lock(
mutex);
368 operator bool()
const 374 #endif // BITCOIN_SYNC_H
void MoveTo(CSemaphoreGrant &grant)
void unlock() UNLOCK_FUNCTION()
#define EXCLUSIVE_LOCK_FUNCTION(...)
reverse_lock(UniqueLock &_lock, const char *_guardname, const char *_file, int _line)
void Enter(const char *pszName, const char *pszFile, int nLine)
RAII-style semaphore lock.
void lock() EXCLUSIVE_LOCK_FUNCTION()
void AssertLockNotHeldInternal(const char *pszName, const char *pszFile, int nLine, MutexType *cs) LOCKS_EXCLUDED(cs)
#define UNLOCK_FUNCTION(...)
CSemaphoreGrant(CSemaphore &sema, bool fTry=false)
void CheckLastCritical(void *cs, std::string &lockname, const char *guardname, const char *file, int line)
void DeleteLock(void *cs)
bool try_lock() EXCLUSIVE_TRYLOCK_FUNCTION(true)
void EnterCritical(const char *pszName, const char *pszFile, int nLine, MutexType *cs, bool fTry=false)
UniqueLock(Mutex *pmutexIn, const char *pszName, const char *pszFile, int nLine, bool fTry=false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn)
UniqueLock(Mutex &mutexIn, const char *pszName, const char *pszFile, int nLine, bool fTry=false) EXCLUSIVE_LOCK_FUNCTION(mutexIn)
~UniqueLock() UNLOCK_FUNCTION()
void AssertLockHeldInternal(const char *pszName, const char *pszFile, int nLine, MutexType *cs) EXCLUSIVE_LOCKS_REQUIRED(cs)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::condition_variable condition
Template mixin that adds -Wthread-safety locking annotations and lock order checking to a subset of t...
#define LOCKS_EXCLUDED(...)
An RAII-style reverse lock.
#define EXCLUSIVE_TRYLOCK_FUNCTION(...)
Wrapper around std::unique_lock style lock for Mutex.
AnnotatedMixin< std::mutex > Mutex
Wrapped mutex: supports waiting but not recursive locking.
bool TryEnter(const char *pszName, const char *pszFile, int nLine)