diff --git a/src/util/stdmutex.h b/src/util/stdmutex.h index 7a3e3039546..2cc05013a59 100644 --- a/src/util/stdmutex.h +++ b/src/util/stdmutex.h @@ -10,6 +10,8 @@ // Thread Safety Analysis and provides appropriate annotation macros. #include // IWYU pragma: export +#include + #include // StdMutex provides an annotated version of std::mutex for us, @@ -23,15 +25,21 @@ public: //! with the ! operator, to indicate that a mutex should not be held. const StdMutex& operator!() const { return *this; } #endif // __clang__ + + // StdMutex::Guard provides an annotated version of std::lock_guard for us. + class SCOPED_LOCKABLE Guard : public std::lock_guard + { + public: + explicit Guard(StdMutex& cs) EXCLUSIVE_LOCK_FUNCTION(cs) : std::lock_guard(cs) {} + ~Guard() UNLOCK_FUNCTION() = default; + }; + + static inline StdMutex& CheckNotHeld(StdMutex& cs) EXCLUSIVE_LOCKS_REQUIRED(!cs) LOCK_RETURNED(cs) { return cs; } }; -// StdLockGuard provides an annotated version of std::lock_guard for us, -// and should only be used when sync.h Mutex/LOCK/etc are not usable. -class SCOPED_LOCKABLE StdLockGuard : public std::lock_guard -{ -public: - explicit StdLockGuard(StdMutex& cs) EXCLUSIVE_LOCK_FUNCTION(cs) : std::lock_guard(cs) {} - ~StdLockGuard() UNLOCK_FUNCTION() = default; -}; +// Provide STDLOCK(..) wrapper around StdMutex::Guard that checks the lock is not already held +#define STDLOCK(cs) StdMutex::Guard UNIQUE_NAME(criticalblock){StdMutex::CheckNotHeld(cs)} + +using StdLockGuard = StdMutex::Guard; // TODO: remove, provided for backwards compat only #endif // BITCOIN_UTIL_STDMUTEX_H