mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-10 22:18:54 +01:00
sync.h: add REVERSE_LOCK
This commit is contained in:
39
src/sync.h
39
src/sync.h
@@ -50,6 +50,7 @@ LEAVE_CRITICAL_SECTION(mutex); // no RAII
|
||||
#ifdef DEBUG_LOCKORDER
|
||||
void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false);
|
||||
void LeaveCritical();
|
||||
void CheckLastCritical(void* cs, std::string& lockname, const char* guardname, const char* file, int line);
|
||||
std::string LocksHeld();
|
||||
void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) ASSERT_EXCLUSIVE_LOCK(cs);
|
||||
void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs);
|
||||
@@ -64,6 +65,7 @@ extern bool g_debug_lockorder_abort;
|
||||
#else
|
||||
void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) {}
|
||||
void static inline LeaveCritical() {}
|
||||
void static inline CheckLastCritical(void* cs, std::string& lockname, const char* guardname, const char* file, int line) {}
|
||||
void static inline AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) ASSERT_EXCLUSIVE_LOCK(cs) {}
|
||||
void static inline AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) {}
|
||||
void static inline DeleteLock(void* cs) {}
|
||||
@@ -171,8 +173,45 @@ public:
|
||||
{
|
||||
return Base::owns_lock();
|
||||
}
|
||||
|
||||
protected:
|
||||
// needed for reverse_lock
|
||||
UniqueLock() { }
|
||||
|
||||
public:
|
||||
/**
|
||||
* An RAII-style reverse lock. Unlocks on construction and locks on destruction.
|
||||
*/
|
||||
class reverse_lock {
|
||||
public:
|
||||
explicit reverse_lock(UniqueLock& _lock, const char* _guardname, const char* _file, int _line) : lock(_lock), file(_file), line(_line) {
|
||||
CheckLastCritical((void*)lock.mutex(), lockname, _guardname, _file, _line);
|
||||
lock.unlock();
|
||||
LeaveCritical();
|
||||
lock.swap(templock);
|
||||
}
|
||||
|
||||
~reverse_lock() {
|
||||
templock.swap(lock);
|
||||
EnterCritical(lockname.c_str(), file.c_str(), line, (void*)lock.mutex());
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
private:
|
||||
reverse_lock(reverse_lock const&);
|
||||
reverse_lock& operator=(reverse_lock const&);
|
||||
|
||||
UniqueLock& lock;
|
||||
UniqueLock templock;
|
||||
std::string lockname;
|
||||
const std::string file;
|
||||
const int line;
|
||||
};
|
||||
friend class reverse_lock;
|
||||
};
|
||||
|
||||
#define REVERSE_LOCK(g) decltype(g)::reverse_lock PASTE2(revlock, __COUNTER__)(g, #g, __FILE__, __LINE__)
|
||||
|
||||
template<typename MutexArg>
|
||||
using DebugLock = UniqueLock<typename std::remove_reference<typename std::remove_pointer<MutexArg>::type>::type>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user