12 #include <condition_variable> 50 #ifdef DEBUG_LOCKORDER 51 void EnterCritical(
const char *pszName,
const char *pszFile,
int nLine,
52 void *
cs,
bool fTry =
false);
55 const char *file,
int line);
56 std::string LocksHeld();
57 template <
typename MutexType>
69 extern bool g_debug_lockorder_abort;
71 static inline void EnterCritical(
const char *pszName,
const char *pszFile,
72 int nLine,
void *
cs,
bool fTry =
false) {}
75 const char *guardname,
const char *file,
77 template <
typename MutexType>
79 const char *pszFile,
int nLine,
83 const char *pszFile,
int nLine,
87 #define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs) 88 #define AssertLockNotHeld(cs) \ 89 AssertLockNotHeldInternal(#cs, __FILE__, __LINE__, &cs) 104 return PARENT::try_lock();
119 #ifdef DEBUG_LOCKCONTENTION 120 void PrintLockContention(
const char *pszName,
const char *pszFile,
int nLine);
124 template <
typename Mutex,
typename Base =
typename Mutex::UniqueLock>
127 void Enter(
const char *pszName,
const char *pszFile,
int nLine) {
128 EnterCritical(pszName, pszFile, nLine, (
void *)(Base::mutex()));
129 #ifdef DEBUG_LOCKCONTENTION 130 if (!Base::try_lock()) {
131 PrintLockContention(pszName, pszFile, nLine);
134 #ifdef DEBUG_LOCKCONTENTION 139 bool TryEnter(
const char *pszName,
const char *pszFile,
int nLine) {
140 EnterCritical(pszName, pszFile, nLine, (
void *)(Base::mutex()),
true);
142 if (!Base::owns_lock()) {
145 return Base::owns_lock();
151 : Base(mutexIn,
std::defer_lock) {
153 TryEnter(pszName, pszFile, nLine);
155 Enter(pszName, pszFile, nLine);
165 *
static_cast<Base *
>(
this) = Base(*pmutexIn, std::defer_lock);
167 TryEnter(pszName, pszFile, nLine);
169 Enter(pszName, pszFile, nLine);
174 if (Base::owns_lock()) {
179 operator bool() {
return Base::owns_lock(); }
193 const char *_file,
int _line)
194 : lock(_lock), file(_file), line(_line) {
205 (
void *)lock.mutex());
222 #define REVERSE_LOCK(g) \ 223 typename std::decay<decltype(g)>::type::reverse_lock PASTE2( \ 224 revlock, __COUNTER__)(g, #g, __FILE__, __LINE__) 226 template <
typename MutexArg>
228 typename std::remove_pointer<MutexArg>::type>::type>;
231 DebugLock<decltype(cs)> PASTE2(criticalblock, \ 232 __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) \ 237 DebugLock<decltype(cs)> name(cs, #cs, __FILE__, __LINE__, true) 238 #define WAIT_LOCK(cs, name) \ 239 DebugLock<decltype(cs)> name(cs, #cs, __FILE__, __LINE__) 241 #define ENTER_CRITICAL_SECTION(cs) \ 243 EnterCritical(#cs, __FILE__, __LINE__, (void *)(&cs)); \ 247 #define LEAVE_CRITICAL_SECTION(cs) \ 261 #define WITH_LOCK(cs, code) \ 277 std::unique_lock<std::mutex> lock(mutex);
278 condition.wait(lock, [&]() {
return value >= 1; });
283 std::lock_guard<std::mutex> lock(mutex);
293 std::lock_guard<std::mutex> lock(mutex);
296 condition.notify_one();
324 if (!fHaveGrant && sem->
try_wait()) {
340 : sem(&sema), fHaveGrant(false) {
350 operator bool()
const {
return fHaveGrant; }
356 template <
typename Mutex>
358 #ifdef DEBUG_LOCKORDER 365 #endif // BITCOIN_SYNC_H static void AssertLockNotHeldInternal(const char *pszName, const char *pszFile, int nLine, void *cs)
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.
static void AssertLockHeldInternal(const char *pszName, const char *pszFile, int nLine, MutexType *cs) ASSERT_EXCLUSIVE_LOCK(cs)
void lock() EXCLUSIVE_LOCK_FUNCTION()
#define UNLOCK_FUNCTION(...)
CSemaphoreGrant(CSemaphore &sema, bool fTry=false)
#define AssertLockHeld(cs)
bool try_lock() EXCLUSIVE_TRYLOCK_FUNCTION(true)
static void DeleteLock(void *cs)
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()
static void CheckLastCritical(void *cs, std::string &lockname, const char *guardname, const char *file, int line)
static void EnterCritical(const char *pszName, const char *pszFile, int nLine, void *cs, bool fTry=false)
static void LeaveCritical()
std::condition_variable condition
Template mixin that adds -Wthread-safety locking annotations and lock order checking to a subset of t...
~LockAssertion() UNLOCK_FUNCTION()
An RAII-style reverse lock.
#define EXCLUSIVE_TRYLOCK_FUNCTION(...)
LockAssertion(Mutex &mutex) EXCLUSIVE_LOCK_FUNCTION(mutex)
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)
#define ASSERT_EXCLUSIVE_LOCK(...)