9 #ifdef DEBUG_LOCKCONTENTION 17 #include <condition_variable> 55 #ifdef DEBUG_LOCKORDER 56 template <
typename MutexType>
57 void EnterCritical(
const char* pszName,
const char* pszFile,
int nLine, MutexType*
cs,
bool fTry =
false);
59 void CheckLastCritical(
void*
cs, std::string& lockname,
const char* guardname,
const char* file,
int line);
60 template <
typename MutexType>
62 template <
typename MutexType>
72 extern bool g_debug_lockorder_abort;
74 template <
typename MutexType>
75 inline void EnterCritical(
const char* pszName,
const char* pszFile,
int nLine, MutexType*
cs,
bool fTry =
false) {}
77 inline void CheckLastCritical(
void*
cs, std::string& lockname,
const char* guardname,
const char* file,
int line) {}
78 template <
typename MutexType>
80 template <
typename MutexType>
90 template <
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) 150 template <
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())
return;
166 bool TryEnter(
const char* pszName,
const char* pszFile,
int nLine)
169 if (Base::try_lock()) {
180 TryEnter(pszName, pszFile, nLine);
182 Enter(pszName, pszFile, nLine);
187 if (!pmutexIn)
return;
189 *
static_cast<Base*
>(
this) =
Base(*pmutexIn, std::defer_lock);
191 TryEnter(pszName, pszFile, nLine);
193 Enter(pszName, pszFile, nLine);
198 if (Base::owns_lock())
204 return Base::owns_lock();
217 explicit reverse_lock(
UniqueLock& _lock,
const char* _guardname,
const char* _file,
int _line) : lock(_lock), file(_file), line(_line) {
226 EnterCritical(lockname.c_str(), file.c_str(), line, lock.mutex());
243 #define REVERSE_LOCK(g) typename std::decay<decltype(g)>::type::reverse_lock UNIQUE_NAME(revlock)(g, #g, __FILE__, __LINE__) 252 template <
typename MutexType>
254 template <
typename MutexType>
257 #define LOCK(cs) UniqueLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__) 258 #define LOCK2(cs1, cs2) \ 259 UniqueLock criticalblock1(MaybeCheckNotHeld(cs1), #cs1, __FILE__, __LINE__); \ 260 UniqueLock criticalblock2(MaybeCheckNotHeld(cs2), #cs2, __FILE__, __LINE__) 261 #define TRY_LOCK(cs, name) UniqueLock name(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__, true) 262 #define WAIT_LOCK(cs, name) UniqueLock name(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__) 264 #define ENTER_CRITICAL_SECTION(cs) \ 266 EnterCritical(#cs, __FILE__, __LINE__, &cs); \ 270 #define LEAVE_CRITICAL_SECTION(cs) \ 272 std::string lockname; \ 273 CheckLastCritical((void*)(&cs), lockname, #cs, __FILE__, __LINE__); \ 301 #define WITH_LOCK(cs, code) (MaybeCheckNotHeld(cs), [&]() -> decltype(auto) { LOCK(cs); code; }()) 326 std::unique_lock<std::mutex> lock(
mutex);
333 std::lock_guard<std::mutex> lock(
mutex);
344 std::lock_guard<std::mutex> lock(
mutex);
394 other.fHaveGrant =
false;
403 other.fHaveGrant =
false;
424 explicit operator bool() const noexcept
430 #endif // BITCOIN_SYNC_H
void unlock() UNLOCK_FUNCTION()
#define EXCLUSIVE_LOCK_FUNCTION(...)
CSemaphoreGrant & operator=(const CSemaphoreGrant &)=delete
(Un)serialize a number as raw byte or 2 hexadecimal chars.
An implementation of a semaphore.
bool TryAcquire() noexcept
~UniqueLock() UNLOCK_FUNCTION()
RAII-style semaphore lock.
void lock() EXCLUSIVE_LOCK_FUNCTION()
void AssertLockNotHeldInternal(const char *pszName, const char *pszFile, int nLine, MutexType *cs) LOCKS_EXCLUDED(cs)
CSemaphoreGrant(CSemaphoreGrant &&other) noexcept
#define UNLOCK_FUNCTION(...)
UniqueLock(MutexType &mutexIn, const char *pszName, const char *pszFile, int nLine, bool fTry=false) EXCLUSIVE_LOCK_FUNCTION(mutexIn)
CSemaphoreGrant() noexcept
void CheckLastCritical(void *cs, std::string &lockname, const char *guardname, const char *file, int line)
void DeleteLock(void *cs)
bool TryEnter(const char *pszName, const char *pszFile, int nLine)
bool try_lock() EXCLUSIVE_TRYLOCK_FUNCTION(true)
void EnterCritical(const char *pszName, const char *pszFile, int nLine, MutexType *cs, bool fTry=false)
#define LOG_TIME_MICROS_WITH_CATEGORY(end_msg, log_category)
reverse_lock(UniqueLock &_lock, const char *_guardname, const char *_file, int _line)
void AssertLockHeldInternal(const char *pszName, const char *pszFile, int nLine, MutexType *cs) EXCLUSIVE_LOCKS_REQUIRED(cs)
CSemaphore & operator=(const CSemaphore &)=delete
CSemaphoreGrant & operator=(CSemaphoreGrant &&other) noexcept
#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.
std::unique_lock< std::recursive_mutex > unique_lock
#define EXCLUSIVE_TRYLOCK_FUNCTION(...)
Mutex & MaybeCheckNotHeld(Mutex &cs) EXCLUSIVE_LOCKS_REQUIRED(!cs) LOCK_RETURNED(cs)
Wrapper around std::unique_lock style lock for MutexType.
void AssertLockNotHeldInline(const char *name, const char *file, int line, Mutex *cs) EXCLUSIVE_LOCKS_REQUIRED(!cs)
Different type to mark Mutex at global scope.
CSemaphore(int init) noexcept
UniqueLock(MutexType *pmutexIn, const char *pszName, const char *pszFile, int nLine, bool fTry=false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn)
CSemaphoreGrant(CSemaphore &sema, bool fTry=false) noexcept
void Enter(const char *pszName, const char *pszFile, int nLine)