12 #include <condition_variable>
50 #ifdef DEBUG_LOCKORDER
51 void EnterCritical(
const char* pszName,
const char* pszFile,
int nLine,
void* cs,
bool fTry =
false);
53 std::string LocksHeld();
54 void AssertLockHeldInternal(
const char* pszName,
const char* pszFile,
int nLine,
void* cs);
55 void AssertLockNotHeldInternal(
const char* pszName,
const char* pszFile,
int nLine,
void* cs);
56 void DeleteLock(
void* cs);
63 extern bool g_debug_lockorder_abort;
65 void static inline EnterCritical(
const char* pszName,
const char* pszFile,
int nLine,
void* cs,
bool fTry =
false) {}
66 void static inline LeaveCritical() {}
67 void static inline AssertLockHeldInternal(
const char* pszName,
const char* pszFile,
int nLine,
void* cs) {}
68 void static inline AssertLockNotHeldInternal(
const char* pszName,
const char* pszFile,
int nLine,
void* cs) {}
69 void static inline DeleteLock(
void* cs) {}
71 #define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs)
72 #define AssertLockNotHeld(cs) AssertLockNotHeldInternal(#cs, __FILE__, __LINE__, &cs)
78 template <
typename PARENT>
83 DeleteLock((
void*)
this);
98 return PARENT::try_lock();
116 #ifdef DEBUG_LOCKCONTENTION
117 void PrintLockContention(
const char* pszName,
const char* pszFile,
int nLine);
121 template <
typename Mutex,
typename Base =
typename Mutex::UniqueLock>
125 void Enter(
const char* pszName,
const char* pszFile,
int nLine)
127 EnterCritical(pszName, pszFile, nLine, (
void*)(Base::mutex()));
128 #ifdef DEBUG_LOCKCONTENTION
129 if (!Base::try_lock()) {
130 PrintLockContention(pszName, pszFile, nLine);
133 #ifdef DEBUG_LOCKCONTENTION
138 bool TryEnter(
const char* pszName,
const char* pszFile,
int nLine)
140 EnterCritical(pszName, pszFile, nLine, (
void*)(Base::mutex()),
true);
142 if (!Base::owns_lock())
144 return Base::owns_lock();
151 TryEnter(pszName, pszFile, nLine);
153 Enter(pszName, pszFile, nLine);
158 if (!pmutexIn)
return;
160 *
static_cast<Base*
>(
this) = Base(*pmutexIn, std::defer_lock);
162 TryEnter(pszName, pszFile, nLine);
164 Enter(pszName, pszFile, nLine);
169 if (Base::owns_lock())
175 return Base::owns_lock();
179 template<
typename MutexArg>
182 #define LOCK(cs) DebugLock<decltype(cs)> PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__)
183 #define LOCK2(cs1, cs2) \
184 DebugLock<decltype(cs1)> criticalblock1(cs1, #cs1, __FILE__, __LINE__); \
185 DebugLock<decltype(cs2)> criticalblock2(cs2, #cs2, __FILE__, __LINE__);
186 #define TRY_LOCK(cs, name) DebugLock<decltype(cs)> name(cs, #cs, __FILE__, __LINE__, true)
187 #define WAIT_LOCK(cs, name) DebugLock<decltype(cs)> name(cs, #cs, __FILE__, __LINE__)
189 #define ENTER_CRITICAL_SECTION(cs) \
191 EnterCritical(#cs, __FILE__, __LINE__, (void*)(&cs)); \
195 #define LEAVE_CRITICAL_SECTION(cs) \
209 #define WITH_LOCK(cs, code) [&] { LOCK(cs); code; }()
223 std::unique_lock<std::mutex> lock(
mutex);
230 std::lock_guard<std::mutex> lock(
mutex);
240 std::lock_guard<std::mutex> lock(
mutex);
301 operator bool()
const
307 #endif // BITCOIN_SYNC_H