| Line | Count | Source | 
| 1 |  | // Copyright (c) 2009-2010 Satoshi Nakamoto | 
| 2 |  | // Copyright (c) 2009-2022 The Bitcoin Core developers | 
| 3 |  | // Distributed under the MIT software license, see the accompanying | 
| 4 |  | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | 
| 5 |  |  | 
| 6 |  | #ifndef BITCOIN_SYNC_H | 
| 7 |  | #define BITCOIN_SYNC_H | 
| 8 |  |  | 
| 9 |  | #ifdef DEBUG_LOCKCONTENTION | 
| 10 |  | #include <logging.h> | 
| 11 |  | #include <logging/timer.h> | 
| 12 |  | #endif | 
| 13 |  |  | 
| 14 |  | #include <threadsafety.h> // IWYU pragma: export | 
| 15 |  | #include <util/macros.h> | 
| 16 |  |  | 
| 17 |  | #include <cassert> | 
| 18 |  | #include <condition_variable> | 
| 19 |  | #include <mutex> | 
| 20 |  | #include <string> | 
| 21 |  | #include <thread> | 
| 22 |  |  | 
| 23 |  | //////////////////////////////////////////////// | 
| 24 |  | //                                            // | 
| 25 |  | // THE SIMPLE DEFINITION, EXCLUDING DEBUG CODE // | 
| 26 |  | //                                            // | 
| 27 |  | //////////////////////////////////////////////// | 
| 28 |  |  | 
| 29 |  | /* | 
| 30 |  | RecursiveMutex mutex; | 
| 31 |  |     std::recursive_mutex mutex; | 
| 32 |  |  | 
| 33 |  | LOCK(mutex); | 
| 34 |  |     std::unique_lock<std::recursive_mutex> criticalblock(mutex); | 
| 35 |  |  | 
| 36 |  | LOCK2(mutex1, mutex2); | 
| 37 |  |     std::unique_lock<std::recursive_mutex> criticalblock1(mutex1); | 
| 38 |  |     std::unique_lock<std::recursive_mutex> criticalblock2(mutex2); | 
| 39 |  |  | 
| 40 |  | TRY_LOCK(mutex, name); | 
| 41 |  |     std::unique_lock<std::recursive_mutex> name(mutex, std::try_to_lock_t); | 
| 42 |  |  */ | 
| 43 |  |  | 
| 44 |  | /////////////////////////////// | 
| 45 |  | //                           // | 
| 46 |  | // THE ACTUAL IMPLEMENTATION // | 
| 47 |  | //                           // | 
| 48 |  | /////////////////////////////// | 
| 49 |  |  | 
| 50 |  | #ifdef DEBUG_LOCKORDER | 
| 51 |  | template <typename MutexType> | 
| 52 |  | void EnterCritical(const char* pszName, const char* pszFile, int nLine, MutexType* cs, bool fTry = false); | 
| 53 |  | void LeaveCritical(); | 
| 54 |  | void CheckLastCritical(void* cs, std::string& lockname, const char* guardname, const char* file, int line); | 
| 55 |  | template <typename MutexType> | 
| 56 |  | void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, MutexType* cs) EXCLUSIVE_LOCKS_REQUIRED(cs); | 
| 57 |  | template <typename MutexType> | 
| 58 |  | void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLine, MutexType* cs) LOCKS_EXCLUDED(cs); | 
| 59 |  | void DeleteLock(void* cs); | 
| 60 |  | bool LockStackEmpty(); | 
| 61 |  |  | 
| 62 |  | /** | 
| 63 |  |  * Call abort() if a potential lock order deadlock bug is detected, instead of | 
| 64 |  |  * just logging information and throwing a logic_error. Defaults to true, and | 
| 65 |  |  * set to false in DEBUG_LOCKORDER unit tests. | 
| 66 |  |  */ | 
| 67 |  | extern bool g_debug_lockorder_abort; | 
| 68 |  | #else | 
| 69 |  | template <typename MutexType> | 
| 70 | 250k | inline void EnterCritical(const char* pszName, const char* pszFile, int nLine, MutexType* cs, bool fTry = false) {}_Z13EnterCriticalISt5mutexEvPKcS2_iPT_b| Line | Count | Source |  | 70 | 32.9k | inline void EnterCritical(const char* pszName, const char* pszFile, int nLine, MutexType* cs, bool fTry = false) {} | 
_Z13EnterCriticalISt15recursive_mutexEvPKcS2_iPT_b| Line | Count | Source |  | 70 | 217k | inline void EnterCritical(const char* pszName, const char* pszFile, int nLine, MutexType* cs, bool fTry = false) {} | 
 | 
| 71 | 250k | inline void LeaveCritical() {} | 
| 72 | 0 | inline void CheckLastCritical(void* cs, std::string& lockname, const char* guardname, const char* file, int line) {} | 
| 73 |  | template <typename MutexType> | 
| 74 | 1 | inline void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, MutexType* cs) EXCLUSIVE_LOCKS_REQUIRED(cs) {}_Z22AssertLockHeldInternalI14AnnotatedMixinISt5mutexEEvPKcS4_iPT_| Line | Count | Source |  | 74 | 1 | inline void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, MutexType* cs) EXCLUSIVE_LOCKS_REQUIRED(cs) {} | 
Unexecuted instantiation: _Z22AssertLockHeldInternalI14AnnotatedMixinISt15recursive_mutexEEvPKcS4_iPT_ | 
| 75 |  | template <typename MutexType> | 
| 76 | 0 | void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLine, MutexType* cs) LOCKS_EXCLUDED(cs) {}Unexecuted instantiation: _Z25AssertLockNotHeldInternalI14AnnotatedMixinISt5mutexEEvPKcS4_iPT_Unexecuted instantiation: _Z25AssertLockNotHeldInternalI14AnnotatedMixinISt15recursive_mutexEEvPKcS4_iPT_Unexecuted instantiation: _Z25AssertLockNotHeldInternalI11GlobalMutexEvPKcS2_iPT_ | 
| 77 | 646 | inline void DeleteLock(void* cs) {} | 
| 78 | 0 | inline bool LockStackEmpty() { return true; } | 
| 79 |  | #endif | 
| 80 |  |  | 
| 81 |  | /** | 
| 82 |  |  * Template mixin that adds -Wthread-safety locking annotations and lock order | 
| 83 |  |  * checking to a subset of the mutex API. | 
| 84 |  |  */ | 
| 85 |  | template <typename PARENT> | 
| 86 |  | class LOCKABLE AnnotatedMixin : public PARENT | 
| 87 |  | { | 
| 88 |  | public: | 
| 89 | 646 |     ~AnnotatedMixin() { | 
| 90 | 646 |         DeleteLock((void*)this); | 
| 91 | 646 |     } _ZN14AnnotatedMixinISt5mutexED2Ev| Line | Count | Source |  | 89 | 24 |     ~AnnotatedMixin() { |  | 90 | 24 |         DeleteLock((void*)this); |  | 91 | 24 |     } | 
_ZN14AnnotatedMixinISt15recursive_mutexED2Ev| Line | Count | Source |  | 89 | 622 |     ~AnnotatedMixin() { |  | 90 | 622 |         DeleteLock((void*)this); |  | 91 | 622 |     } | 
 | 
| 92 |  |  | 
| 93 |  |     void lock() EXCLUSIVE_LOCK_FUNCTION() | 
| 94 |  |     { | 
| 95 |  |         PARENT::lock(); | 
| 96 |  |     } | 
| 97 |  |  | 
| 98 |  |     void unlock() UNLOCK_FUNCTION() | 
| 99 |  |     { | 
| 100 |  |         PARENT::unlock(); | 
| 101 |  |     } | 
| 102 |  |  | 
| 103 |  |     bool try_lock() EXCLUSIVE_TRYLOCK_FUNCTION(true) | 
| 104 |  |     { | 
| 105 |  |         return PARENT::try_lock(); | 
| 106 |  |     } | 
| 107 |  |  | 
| 108 |  |     using unique_lock = std::unique_lock<PARENT>; | 
| 109 |  | #ifdef __clang__ | 
| 110 |  |     //! For negative capabilities in the Clang Thread Safety Analysis. | 
| 111 |  |     //! A negative requirement uses the EXCLUSIVE_LOCKS_REQUIRED attribute, in conjunction | 
| 112 |  |     //! with the ! operator, to indicate that a mutex should not be held. | 
| 113 |  |     const AnnotatedMixin& operator!() const { return *this; } | 
| 114 |  | #endif // __clang__ | 
| 115 |  | }; | 
| 116 |  |  | 
| 117 |  | /** | 
| 118 |  |  * Wrapped mutex: supports recursive locking, but no waiting | 
| 119 |  |  * TODO: We should move away from using the recursive lock by default. | 
| 120 |  |  */ | 
| 121 |  | using RecursiveMutex = AnnotatedMixin<std::recursive_mutex>; | 
| 122 |  |  | 
| 123 |  | /** Wrapped mutex: supports waiting but not recursive locking */ | 
| 124 |  | using Mutex = AnnotatedMixin<std::mutex>; | 
| 125 |  |  | 
| 126 |  | /** Different type to mark Mutex at global scope | 
| 127 |  |  * | 
| 128 |  |  * Thread safety analysis can't handle negative assertions about mutexes | 
| 129 |  |  * with global scope well, so mark them with a separate type, and | 
| 130 |  |  * eventually move all the mutexes into classes so they are not globally | 
| 131 |  |  * visible. | 
| 132 |  |  * | 
| 133 |  |  * See: https://github.com/bitcoin/bitcoin/pull/20272#issuecomment-720755781 | 
| 134 |  |  */ | 
| 135 |  | class GlobalMutex : public Mutex { }; | 
| 136 |  |  | 
| 137 | 1 | #define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs) | 
| 138 |  |  | 
| 139 | 0 | inline void AssertLockNotHeldInline(const char* name, const char* file, int line, Mutex* cs) EXCLUSIVE_LOCKS_REQUIRED(!cs) { AssertLockNotHeldInternal(name, file, line, cs); } | 
| 140 | 0 | inline void AssertLockNotHeldInline(const char* name, const char* file, int line, RecursiveMutex* cs) LOCKS_EXCLUDED(cs) { AssertLockNotHeldInternal(name, file, line, cs); } | 
| 141 | 0 | inline void AssertLockNotHeldInline(const char* name, const char* file, int line, GlobalMutex* cs) LOCKS_EXCLUDED(cs) { AssertLockNotHeldInternal(name, file, line, cs); } | 
| 142 | 0 | #define AssertLockNotHeld(cs) AssertLockNotHeldInline(#cs, __FILE__, __LINE__, &cs) | 
| 143 |  |  | 
| 144 |  | /** Wrapper around std::unique_lock style lock for MutexType. */ | 
| 145 |  | template <typename MutexType> | 
| 146 |  | class SCOPED_LOCKABLE UniqueLock : public MutexType::unique_lock | 
| 147 |  | { | 
| 148 |  | private: | 
| 149 |  |     using Base = typename MutexType::unique_lock; | 
| 150 |  |  | 
| 151 |  |     void Enter(const char* pszName, const char* pszFile, int nLine) | 
| 152 | 250k |     { | 
| 153 | 250k |         EnterCritical(pszName, pszFile, nLine, Base::mutex()); | 
| 154 |  | #ifdef DEBUG_LOCKCONTENTION | 
| 155 |  |         if (Base::try_lock()) return; | 
| 156 |  |         LOG_TIME_MICROS_WITH_CATEGORY(strprintf("lock contention %s, %s:%d", pszName, pszFile, nLine), BCLog::LOCK); | 
| 157 |  | #endif | 
| 158 | 250k |         Base::lock(); | 
| 159 | 250k |     } _ZN10UniqueLockI14AnnotatedMixinISt5mutexEE5EnterEPKcS5_i| Line | Count | Source |  | 152 | 32.9k |     { |  | 153 | 32.9k |         EnterCritical(pszName, pszFile, nLine, Base::mutex()); |  | 154 |  | #ifdef DEBUG_LOCKCONTENTION |  | 155 |  |         if (Base::try_lock()) return; |  | 156 |  |         LOG_TIME_MICROS_WITH_CATEGORY(strprintf("lock contention %s, %s:%d", pszName, pszFile, nLine), BCLog::LOCK); |  | 157 |  | #endif |  | 158 | 32.9k |         Base::lock(); |  | 159 | 32.9k |     } | 
_ZN10UniqueLockI14AnnotatedMixinISt15recursive_mutexEE5EnterEPKcS5_i| Line | Count | Source |  | 152 | 217k |     { |  | 153 | 217k |         EnterCritical(pszName, pszFile, nLine, Base::mutex()); |  | 154 |  | #ifdef DEBUG_LOCKCONTENTION |  | 155 |  |         if (Base::try_lock()) return; |  | 156 |  |         LOG_TIME_MICROS_WITH_CATEGORY(strprintf("lock contention %s, %s:%d", pszName, pszFile, nLine), BCLog::LOCK); |  | 157 |  | #endif |  | 158 | 217k |         Base::lock(); |  | 159 | 217k |     } | 
Unexecuted instantiation: _ZN10UniqueLockI11GlobalMutexE5EnterEPKcS3_i | 
| 160 |  |  | 
| 161 |  |     bool TryEnter(const char* pszName, const char* pszFile, int nLine) | 
| 162 | 0 |     { | 
| 163 | 0 |         EnterCritical(pszName, pszFile, nLine, Base::mutex(), true); | 
| 164 | 0 |         if (Base::try_lock()) { | 
| 165 | 0 |             return true; | 
| 166 | 0 |         } | 
| 167 | 0 |         LeaveCritical(); | 
| 168 | 0 |         return false; | 
| 169 | 0 |     } Unexecuted instantiation: _ZN10UniqueLockI14AnnotatedMixinISt5mutexEE8TryEnterEPKcS5_iUnexecuted instantiation: _ZN10UniqueLockI14AnnotatedMixinISt15recursive_mutexEE8TryEnterEPKcS5_iUnexecuted instantiation: _ZN10UniqueLockI11GlobalMutexE8TryEnterEPKcS3_i | 
| 170 |  |  | 
| 171 |  | public: | 
| 172 | 250k |     UniqueLock(MutexType& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : Base(mutexIn, std::defer_lock) | 
| 173 | 250k |     { | 
| 174 | 250k |         if (fTry) | 
| 175 | 0 |             TryEnter(pszName, pszFile, nLine); | 
| 176 | 250k |         else | 
| 177 | 250k |             Enter(pszName, pszFile, nLine); | 
| 178 | 250k |     } _ZN10UniqueLockI14AnnotatedMixinISt5mutexEEC2ERS2_PKcS6_ib| Line | Count | Source |  | 172 | 32.9k |     UniqueLock(MutexType& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : Base(mutexIn, std::defer_lock) |  | 173 | 32.9k |     { |  | 174 | 32.9k |         if (fTry) |  | 175 | 0 |             TryEnter(pszName, pszFile, nLine); |  | 176 | 32.9k |         else |  | 177 | 32.9k |             Enter(pszName, pszFile, nLine); |  | 178 | 32.9k |     } | 
_ZN10UniqueLockI14AnnotatedMixinISt15recursive_mutexEEC2ERS2_PKcS6_ib| Line | Count | Source |  | 172 | 217k |     UniqueLock(MutexType& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : Base(mutexIn, std::defer_lock) |  | 173 | 217k |     { |  | 174 | 217k |         if (fTry) |  | 175 | 0 |             TryEnter(pszName, pszFile, nLine); |  | 176 | 217k |         else |  | 177 | 217k |             Enter(pszName, pszFile, nLine); |  | 178 | 217k |     } | 
Unexecuted instantiation: _ZN10UniqueLockI11GlobalMutexEC2ERS0_PKcS4_ib | 
| 179 |  |  | 
| 180 |  |     UniqueLock(MutexType* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn) | 
| 181 | 0 |     { | 
| 182 | 0 |         if (!pmutexIn) return; | 
| 183 |  |  | 
| 184 | 0 |         *static_cast<Base*>(this) = Base(*pmutexIn, std::defer_lock); | 
| 185 | 0 |         if (fTry) | 
| 186 | 0 |             TryEnter(pszName, pszFile, nLine); | 
| 187 | 0 |         else | 
| 188 | 0 |             Enter(pszName, pszFile, nLine); | 
| 189 | 0 |     } | 
| 190 |  |  | 
| 191 |  |     ~UniqueLock() UNLOCK_FUNCTION() | 
| 192 | 250k |     { | 
| 193 | 250k |         if (Base::owns_lock()) | 
| 194 | 250k |             LeaveCritical(); | 
| 195 | 250k |     } _ZN10UniqueLockI14AnnotatedMixinISt5mutexEED2Ev| Line | Count | Source |  | 192 | 32.9k |     { |  | 193 | 32.9k |         if (Base::owns_lock()) |  | 194 | 32.9k |             LeaveCritical(); |  | 195 | 32.9k |     } | 
_ZN10UniqueLockI14AnnotatedMixinISt15recursive_mutexEED2Ev| Line | Count | Source |  | 192 | 217k |     { |  | 193 | 217k |         if (Base::owns_lock()) |  | 194 | 217k |             LeaveCritical(); |  | 195 | 217k |     } | 
Unexecuted instantiation: _ZN10UniqueLockI11GlobalMutexED2Ev | 
| 196 |  |  | 
| 197 |  |     operator bool() | 
| 198 | 0 |     { | 
| 199 | 0 |         return Base::owns_lock(); | 
| 200 | 0 |     } Unexecuted instantiation: _ZN10UniqueLockI14AnnotatedMixinISt15recursive_mutexEEcvbEvUnexecuted instantiation: _ZN10UniqueLockI14AnnotatedMixinISt5mutexEEcvbEv | 
| 201 |  |  | 
| 202 |  | protected: | 
| 203 |  |     // needed for reverse_lock | 
| 204 | 0 |     UniqueLock() = default; Unexecuted instantiation: _ZN10UniqueLockI14AnnotatedMixinISt15recursive_mutexEEC2EvUnexecuted instantiation: _ZN10UniqueLockI14AnnotatedMixinISt5mutexEEC2Ev | 
| 205 |  |  | 
| 206 |  | public: | 
| 207 |  |     /** | 
| 208 |  |      * An RAII-style reverse lock. Unlocks on construction and locks on destruction. | 
| 209 |  |      */ | 
| 210 |  |     class SCOPED_LOCKABLE reverse_lock { | 
| 211 |  |     public: | 
| 212 | 0 |         explicit reverse_lock(UniqueLock& _lock, const MutexType& mutex, const char* _guardname, const char* _file, int _line) UNLOCK_FUNCTION(mutex) : lock(_lock), file(_file), line(_line) { | 
| 213 |  |             // Ensure that mutex passed back for thread-safety analysis is indeed the original | 
| 214 | 0 |             assert(std::addressof(mutex) == lock.mutex()); | 
| 215 |  |  | 
| 216 | 0 |             CheckLastCritical((void*)lock.mutex(), lockname, _guardname, _file, _line); | 
| 217 | 0 |             lock.unlock(); | 
| 218 | 0 |             LeaveCritical(); | 
| 219 | 0 |             lock.swap(templock); | 
| 220 | 0 |         } Unexecuted instantiation: _ZN10UniqueLockI14AnnotatedMixinISt15recursive_mutexEE12reverse_lockC2ERS3_RKS2_PKcS9_iUnexecuted instantiation: _ZN10UniqueLockI14AnnotatedMixinISt5mutexEE12reverse_lockC2ERS3_RKS2_PKcS9_i | 
| 221 |  |  | 
| 222 | 0 |         ~reverse_lock() UNLOCK_FUNCTION() { | 
| 223 | 0 |             templock.swap(lock); | 
| 224 | 0 |             EnterCritical(lockname.c_str(), file.c_str(), line, lock.mutex()); | 
| 225 | 0 |             lock.lock(); | 
| 226 | 0 |         } Unexecuted instantiation: _ZN10UniqueLockI14AnnotatedMixinISt15recursive_mutexEE12reverse_lockD2EvUnexecuted instantiation: _ZN10UniqueLockI14AnnotatedMixinISt5mutexEE12reverse_lockD2Ev | 
| 227 |  |  | 
| 228 |  |      private: | 
| 229 |  |         reverse_lock(reverse_lock const&); | 
| 230 |  |         reverse_lock& operator=(reverse_lock const&); | 
| 231 |  |  | 
| 232 |  |         UniqueLock& lock; | 
| 233 |  |         UniqueLock templock; | 
| 234 |  |         std::string lockname; | 
| 235 |  |         const std::string file; | 
| 236 |  |         const int line; | 
| 237 |  |      }; | 
| 238 |  |      friend class reverse_lock; | 
| 239 |  | }; | 
| 240 |  |  | 
| 241 |  | // clang's thread-safety analyzer is unable to deal with aliases of mutexes, so | 
| 242 |  | // it is not possible to use the lock's copy of the mutex for that purpose. | 
| 243 |  | // Instead, the original mutex needs to be passed back to the reverse_lock for | 
| 244 |  | // the sake of thread-safety analysis, but it is not actually used otherwise. | 
| 245 | 18.4E | #define REVERSE_LOCK(g, cs) typename std::decay<decltype(g)>::type::reverse_lock UNIQUE_NAME(revlock)(g, cs, #cs, __FILE__, __LINE__) | 
| 246 |  |  | 
| 247 |  | // When locking a Mutex, require negative capability to ensure the lock | 
| 248 |  | // is not already held | 
| 249 | 32.9k | inline Mutex& MaybeCheckNotHeld(Mutex& cs) EXCLUSIVE_LOCKS_REQUIRED(!cs) LOCK_RETURNED(cs) { return cs; } | 
| 250 | 0 | inline Mutex* MaybeCheckNotHeld(Mutex* cs) EXCLUSIVE_LOCKS_REQUIRED(!cs) LOCK_RETURNED(cs) { return cs; } | 
| 251 |  |  | 
| 252 |  | // When locking a GlobalMutex or RecursiveMutex, just check it is not | 
| 253 |  | // locked in the surrounding scope. | 
| 254 |  | template <typename MutexType> | 
| 255 | 217k | inline MutexType& MaybeCheckNotHeld(MutexType& m) LOCKS_EXCLUDED(m) LOCK_RETURNED(m) { return m; }_Z17MaybeCheckNotHeldI14AnnotatedMixinISt15recursive_mutexEERT_S4_| Line | Count | Source |  | 255 | 217k | inline MutexType& MaybeCheckNotHeld(MutexType& m) LOCKS_EXCLUDED(m) LOCK_RETURNED(m) { return m; } | 
Unexecuted instantiation: _Z17MaybeCheckNotHeldI11GlobalMutexERT_S2_ | 
| 256 |  | template <typename MutexType> | 
| 257 | 0 | inline MutexType* MaybeCheckNotHeld(MutexType* m) LOCKS_EXCLUDED(m) LOCK_RETURNED(m) { return m; } | 
| 258 |  |  | 
| 259 | 250k | #define LOCK(cs) UniqueLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__) | 
| 260 |  | #define LOCK2(cs1, cs2)                                               \ | 
| 261 | 0 |     UniqueLock criticalblock1(MaybeCheckNotHeld(cs1), #cs1, __FILE__, __LINE__); \ | 
| 262 | 0 |     UniqueLock criticalblock2(MaybeCheckNotHeld(cs2), #cs2, __FILE__, __LINE__) | 
| 263 | 0 | #define LOCK_ARGS(cs) MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__ | 
| 264 | 0 | #define TRY_LOCK(cs, name) UniqueLock name(LOCK_ARGS(cs), true) | 
| 265 | 0 | #define WAIT_LOCK(cs, name) UniqueLock name(LOCK_ARGS(cs)) | 
| 266 |  |  | 
| 267 |  | //! Run code while locking a mutex. | 
| 268 |  | //! | 
| 269 |  | //! Examples: | 
| 270 |  | //! | 
| 271 |  | //!   WITH_LOCK(cs, shared_val = shared_val + 1); | 
| 272 |  | //! | 
| 273 |  | //!   int val = WITH_LOCK(cs, return shared_val); | 
| 274 |  | //! | 
| 275 |  | //! Note: | 
| 276 |  | //! | 
| 277 |  | //! Since the return type deduction follows that of decltype(auto), while the | 
| 278 |  | //! deduced type of: | 
| 279 |  | //! | 
| 280 |  | //!   WITH_LOCK(cs, return {int i = 1; return i;}); | 
| 281 |  | //! | 
| 282 |  | //! is int, the deduced type of: | 
| 283 |  | //! | 
| 284 |  | //!   WITH_LOCK(cs, return {int j = 1; return (j);}); | 
| 285 |  | //! | 
| 286 |  | //! is &int, a reference to a local variable | 
| 287 |  | //! | 
| 288 |  | //! The above is detectable at compile-time with the -Wreturn-local-addr flag in | 
| 289 |  | //! gcc and the -Wreturn-stack-address flag in clang, both enabled by default. | 
| 290 | 3 | #define WITH_LOCK(cs, code) (MaybeCheckNotHeld(cs), [&]() -> decltype(auto) { LOCK(cs); code; }())Unexecuted instantiation: _ZZN20AddrManDeterministicC1ERK15NetGroupManagerR18FuzzedDataProvideriENKUlvE_clEvUnexecuted instantiation: block_index.cpp:_ZZ23block_index_fuzz_targetSt4spanIKhLm18446744073709551615EEENK3$_1clEvUnexecuted instantiation: chain.cpp:_ZZ17chain_fuzz_targetSt4spanIKhLm18446744073709551615EEENK3$_0clEvUnexecuted instantiation: checkqueue.cpp:_ZZN11CCheckQueueIN12_GLOBAL__N_19DumbCheckEiED1EvENKUlvE_clEvUnexecuted instantiation: p2p_headers_presync.cpp:_ZZ31p2p_headers_presync_fuzz_targetSt4spanIKhLm18446744073709551615EEENK3$_0clEvUnexecuted instantiation: p2p_headers_presync.cpp:_ZZ31p2p_headers_presync_fuzz_targetSt4spanIKhLm18446744073709551615EEENK3$_1clEvUnexecuted instantiation: _ZZNK11V1Transport23ReceivedMessageCompleteEvENKUlvE_clEvUnexecuted instantiation: package_eval.cpp:_ZZN12_GLOBAL__N_134ephemeral_package_eval_fuzz_targetESt4spanIKhLm18446744073709551615EEENK3$_1clEvUnexecuted instantiation: package_eval.cpp:_ZZN12_GLOBAL__N_134ephemeral_package_eval_fuzz_targetESt4spanIKhLm18446744073709551615EEENK3$_2clEvUnexecuted instantiation: package_eval.cpp:_ZZN12_GLOBAL__N_134ephemeral_package_eval_fuzz_targetESt4spanIKhLm18446744073709551615EEENK3$_3clEvUnexecuted instantiation: package_eval.cpp:_ZZN12_GLOBAL__N_118initialize_tx_poolEvENK3$_0clEvUnexecuted instantiation: package_eval.cpp:_ZZN12_GLOBAL__N_127tx_package_eval_fuzz_targetESt4spanIKhLm18446744073709551615EEENK3$_1clEvUnexecuted instantiation: package_eval.cpp:_ZZN12_GLOBAL__N_127tx_package_eval_fuzz_targetESt4spanIKhLm18446744073709551615EEENK3$_2clEvUnexecuted instantiation: package_eval.cpp:_ZZN12_GLOBAL__N_127tx_package_eval_fuzz_targetESt4spanIKhLm18446744073709551615EEENK3$_3clEvUnexecuted instantiation: process_message.cpp:_ZZ27process_message_fuzz_targetSt4spanIKhLm18446744073709551615EEENK3$_0clEvUnexecuted instantiation: process_message.cpp:_ZZ27process_message_fuzz_targetSt4spanIKhLm18446744073709551615EEENK3$_1clEvUnexecuted instantiation: process_messages.cpp:_ZZ28process_messages_fuzz_targetSt4spanIKhLm18446744073709551615EEENK3$_0clEvUnexecuted instantiation: process_messages.cpp:_ZZ28process_messages_fuzz_targetSt4spanIKhLm18446744073709551615EEENK3$_1clEvUnexecuted instantiation: tx_pool.cpp:_ZZN12_GLOBAL__N_128tx_pool_standard_fuzz_targetESt4spanIKhLm18446744073709551615EEENK3$_1clEvUnexecuted instantiation: tx_pool.cpp:_ZZN12_GLOBAL__N_128tx_pool_standard_fuzz_targetESt4spanIKhLm18446744073709551615EEENK3$_3clEvUnexecuted instantiation: tx_pool.cpp:_ZZN12_GLOBAL__N_128tx_pool_standard_fuzz_targetESt4spanIKhLm18446744073709551615EEENK3$_5clEvUnexecuted instantiation: tx_pool.cpp:_ZZN12_GLOBAL__N_128tx_pool_standard_fuzz_targetESt4spanIKhLm18446744073709551615EEENK3$_6clEvUnexecuted instantiation: tx_pool.cpp:_ZZN12_GLOBAL__N_16FinishER18FuzzedDataProviderRNS_12MockedTxPoolER10ChainstateENK3$_0clEvUnexecuted instantiation: tx_pool.cpp:_ZZN12_GLOBAL__N_16FinishER18FuzzedDataProviderRNS_12MockedTxPoolER10ChainstateENK3$_1clEvUnexecuted instantiation: tx_pool.cpp:_ZZN12_GLOBAL__N_16FinishER18FuzzedDataProviderRNS_12MockedTxPoolER10ChainstateENK3$_2clEvUnexecuted instantiation: tx_pool.cpp:_ZZN12_GLOBAL__N_118initialize_tx_poolEvENK3$_0clEvUnexecuted instantiation: tx_pool.cpp:_ZZN12_GLOBAL__N_119tx_pool_fuzz_targetESt4spanIKhLm18446744073709551615EEENK3$_0clEvUnexecuted instantiation: utxo_snapshot.cpp:_ZZN12_GLOBAL__N_118utxo_snapshot_fuzzILb0EEEvSt4spanIKhLm18446744073709551615EEENKUlvE0_clEvUnexecuted instantiation: utxo_snapshot.cpp:_ZZN12_GLOBAL__N_116initialize_chainILb1EEEvvENKUlvE_clEvUnexecuted instantiation: scriptpubkeyman.cpp:_ZZN6wallet14LegacyDataSPKM19MigrateToDescriptorEvENK3$_0clEvUnexecuted instantiation: scriptpubkeyman.cpp:_ZZN6wallet14LegacyDataSPKM19MigrateToDescriptorEvENK3$_1clEvUnexecuted instantiation: scriptpubkeyman.cpp:_ZZN6wallet14LegacyDataSPKM19MigrateToDescriptorEvENK3$_2clEvUnexecuted instantiation: wallet.cpp:_ZZN6wallet12RemoveWalletERNS_13WalletContextERKSt10shared_ptrINS_7CWalletEESt8optionalIbERSt6vectorI13bilingual_strSaISA_EEENK3$_0clEvUnexecuted instantiation: wallet.cpp:_ZZN6wallet10LoadWalletERNS_13WalletContextERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt8optionalIbERKNS_15DatabaseOptionsERNS_14DatabaseStatusER13bilingual_strRSt6vectorISH_SaISH_EEENK3$_0clB5cxx11EvUnexecuted instantiation: wallet.cpp:_ZZN6wallet10LoadWalletERNS_13WalletContextERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt8optionalIbERKNS_15DatabaseOptionsERNS_14DatabaseStatusER13bilingual_strRSt6vectorISH_SaISH_EEENK3$_1clEvUnexecuted instantiation: wallet.cpp:_ZZNK6wallet7CWallet30BlockUntilSyncedToCurrentChainEvENK3$_0clEvUnexecuted instantiation: wallet.cpp:_ZZN6wallet7CWallet14RescanFromTimeElRKNS_20WalletRescanReserverEbENK3$_0clEvUnexecuted instantiation: wallet.cpp:_ZZN6wallet7CWallet25ScanForWalletTransactionsERK7uint256iSt8optionalIiERKNS_20WalletRescanReserverEbbENK3$_0clEvUnexecuted instantiation: wallet.cpp:_ZZN6wallet7CWallet25ScanForWalletTransactionsERK7uint256iSt8optionalIiERKNS_20WalletRescanReserverEbbENK3$_1clEvUnexecuted instantiation: wallet.cpp:_ZZN6wallet7CWallet25ScanForWalletTransactionsERK7uint256iSt8optionalIiERKNS_20WalletRescanReserverEbbENK3$_2clEvUnexecuted instantiation: wallet.cpp:_ZZN6wallet7CWallet25ScanForWalletTransactionsERK7uint256iSt8optionalIiERKNS_20WalletRescanReserverEbbENK3$_3clEvUnexecuted instantiation: wallet.cpp:_ZZN6wallet7CWallet15postInitProcessEvENK3$_0clEvUnexecuted instantiation: wallet.cpp:_ZZNK6wallet7CWallet12BackupWalletERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEENK3$_0clEvUnexecuted instantiation: mining.cpp:_ZZ12ProcessBlockRKN4node11NodeContextERKSt10shared_ptrI6CBlockEENK3$_0clEv_ZZN10CScheduler4stopEvENKUlvE_clEv| Line | Count | Source |  | 290 | 1 | #define WITH_LOCK(cs, code) (MaybeCheckNotHeld(cs), [&]() -> decltype(auto) { LOCK(cs); code; }()) | 
Unexecuted instantiation: _ZZN18HTTPRequestTracker10AddRequestEP14evhttp_requestENKUlvE_clEvUnexecuted instantiation: _ZZNK18HTTPRequestTracker22CountActiveConnectionsEvENKUlvE_clEvUnexecuted instantiation: init.cpp:_ZZ11AppInitMainRN4node11NodeContextEPN10interfaces21BlockAndHeaderTipInfoEENK3$_8clEvUnexecuted instantiation: init.cpp:_ZZ11AppInitMainRN4node11NodeContextEPN10interfaces21BlockAndHeaderTipInfoEENK3$_9clEvUnexecuted instantiation: init.cpp:_ZZ24StartIndexBackgroundSyncRN4node11NodeContextEENK3$_0clEvUnexecuted instantiation: init.cpp:_ZZZ11InitContextRN4node11NodeContextEENK3$_0clEvENKUlvE_clEvUnexecuted instantiation: coinstats.cpp:_ZZN6kernel16ComputeUTXOStatsENS_17CoinStatsHashTypeEP10CCoinsViewRN4node12BlockManagerERKSt8functionIFvvEEENK3$_0clEvUnexecuted instantiation: net.cpp:_ZZN8CConnman13AddConnectionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14ConnectionTypebENK3$_0clEvUnexecuted instantiation: net.cpp:_ZZN8CConnman22SocketHandlerConnectedERKSt6vectorIP5CNodeSaIS2_EERKSt13unordered_mapISt10shared_ptrIK4SockENS9_6EventsENS9_17HashSharedPtrSockENS9_18EqualSharedPtrSockESaISt4pairIKSB_SC_EEEENK3$_0clEvnet.cpp:_ZZN8CConnman9StopNodesEvENK3$_0clEv| Line | Count | Source |  | 290 | 1 | #define WITH_LOCK(cs, code) (MaybeCheckNotHeld(cs), [&]() -> decltype(auto) { LOCK(cs); code; }()) | 
Unexecuted instantiation: net_processing.cpp:_ZZN12_GLOBAL__N_14Peer10GetTxRelayEvENKUlvE_clEvUnexecuted instantiation: net_processing.cpp:_ZZNK12_GLOBAL__N_115PeerManagerImpl17GetNodeStateStatsElR15CNodeStateStatsENK3$_0clEvUnexecuted instantiation: net_processing.cpp:_ZZN12_GLOBAL__N_115PeerManagerImpl14ProcessMessageER5CNodeRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEER10DataStreamNSt6chrono8durationIlSt5ratioILl1ELl1000000EEEERKSt6atomicIbEENK3$_0clEvUnexecuted instantiation: net_processing.cpp:_ZZN12_GLOBAL__N_115PeerManagerImpl14ProcessMessageER5CNodeRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEER10DataStreamNSt6chrono8durationIlSt5ratioILl1ELl1000000EEEERKSt6atomicIbEENK3$_2clEvUnexecuted instantiation: net_processing.cpp:_ZZN12_GLOBAL__N_115PeerManagerImpl19ProcessGetBlockDataER5CNodeRNS_4PeerERK4CInvENK3$_0clEvUnexecuted instantiation: net_processing.cpp:_ZZN12_GLOBAL__N_115PeerManagerImpl19ProcessGetBlockDataER5CNodeRNS_4PeerERK4CInvENK3$_1clEvUnexecuted instantiation: net_processing.cpp:_ZZN12_GLOBAL__N_115PeerManagerImpl14ProcessMessageER5CNodeRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEER10DataStreamNSt6chrono8durationIlSt5ratioILl1ELl1000000EEEERKSt6atomicIbEENK3$_3clEvUnexecuted instantiation: net_processing.cpp:_ZZN12_GLOBAL__N_115PeerManagerImpl14ProcessMessageER5CNodeRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEER10DataStreamNSt6chrono8durationIlSt5ratioILl1ELl1000000EEEERKSt6atomicIbEENK3$_4clEvUnexecuted instantiation: net_processing.cpp:_ZZN12_GLOBAL__N_115PeerManagerImpl14ProcessMessageER5CNodeRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEER10DataStreamNSt6chrono8durationIlSt5ratioILl1ELl1000000EEEERKSt6atomicIbEENK3$_5clEvUnexecuted instantiation: net_processing.cpp:_ZZN12_GLOBAL__N_115PeerManagerImpl21ProcessHeadersMessageER5CNodeRNS_4PeerEOSt6vectorI12CBlockHeaderSaIS6_EEbENK3$_0clEvUnexecuted instantiation: net_processing.cpp:_ZZN12_GLOBAL__N_115PeerManagerImpl25HandleUnconnectingHeadersER5CNodeRNS_4PeerERKSt6vectorI12CBlockHeaderSaIS6_EEENK3$_0clEvUnexecuted instantiation: net_processing.cpp:_ZZN12_GLOBAL__N_115PeerManagerImpl25HandleUnconnectingHeadersER5CNodeRNS_4PeerERKSt6vectorI12CBlockHeaderSaIS6_EEENK3$_1clEvUnexecuted instantiation: net_processing.cpp:_ZZN12_GLOBAL__N_115PeerManagerImpl14ProcessMessageER5CNodeRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEER10DataStreamNSt6chrono8durationIlSt5ratioILl1ELl1000000EEEERKSt6atomicIbEENK3$_6clEvUnexecuted instantiation: net_processing.cpp:_ZZN12_GLOBAL__N_115PeerManagerImpl14ProcessMessageER5CNodeRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEER10DataStreamNSt6chrono8durationIlSt5ratioILl1ELl1000000EEEERKSt6atomicIbEENK3$_7clEvUnexecuted instantiation: net_processing.cpp:_ZZN12_GLOBAL__N_115PeerManagerImpl14InitializeNodeERK5CNode12ServiceFlagsENK3$_0clEvUnexecuted instantiation: net_processing.cpp:_ZZN12_GLOBAL__N_115PeerManagerImpl12FinalizeNodeERK5CNodeENK3$_0clEvUnexecuted instantiation: blockstorage.cpp:_ZZN4node12BlockManager17WriteBlockIndexDBEvENK3$_0clEvUnexecuted instantiation: blockstorage.cpp:_ZZN4node12BlockManager31ScanAndUnlinkAlreadyPrunedFilesEvENK3$_0clEvUnexecuted instantiation: blockstorage.cpp:_ZZNK4node12BlockManager13ReadBlockUndoER10CBlockUndoRK11CBlockIndexENK3$_0clEvUnexecuted instantiation: blockstorage.cpp:_ZZNK4node12BlockManager9ReadBlockER6CBlockRK11CBlockIndexENK3$_0clEvUnexecuted instantiation: blockstorage.cpp:_ZZN4node12ImportBlocksER17ChainstateManagerSt4spanIKN2fs4pathELm18446744073709551615EEENK3$_0clEvUnexecuted instantiation: blockstorage.cpp:_ZZN4node12ImportBlocksER17ChainstateManagerSt4spanIKN2fs4pathELm18446744073709551615EEENK3$_1clEvUnexecuted instantiation: interfaces.cpp:_ZZN4node12_GLOBAL__N_18NodeImpl16getBestBlockHashEvENKUlvE_clEvUnexecuted instantiation: interfaces.cpp:_ZZN4node12_GLOBAL__N_19ChainImpl9getHeightEvENKUlvE_clEvUnexecuted instantiation: interfaces.cpp:_ZZN4node12_GLOBAL__N_19ChainImpl21blockFilterMatchesAnyE15BlockFilterTypeRK7uint256RKSt13unordered_setISt6vectorIhSaIhEE14ByteVectorHashSt8equal_toIS9_ESaIS9_EEENKUlvE_clEvUnexecuted instantiation: interfaces.cpp:_ZZN4node12_GLOBAL__N_19ChainImpl32waitForNotificationsIfTipChangedERK7uint256ENKUlvE_clEvUnexecuted instantiation: miner.cpp:_ZZN4node21RegenerateCommitmentsER6CBlockR17ChainstateManagerENK3$_0clEvUnexecuted instantiation: warnings.cpp:_ZZN4node8Warnings3SetESt7variantIJN6kernel7WarningENS_7WarningEEE13bilingual_strENK3$_0clEvUnexecuted instantiation: warnings.cpp:_ZZN4node8Warnings5UnsetESt7variantIJN6kernel7WarningENS_7WarningEEEENK3$_0clEvUnexecuted instantiation: fees.cpp:_ZZN16FeeFilterRounder5roundElENK3$_0clEvUnexecuted instantiation: rest.cpp:_ZZL19rest_deploymentinfoRKSt3anyP11HTTPRequestRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEENK3$_0clEvUnexecuted instantiation: rest.cpp:_ZZL17rest_spent_txoutsRKSt3anyP11HTTPRequestRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEENK3$_0clEvUnexecuted instantiation: blockchain.cpp:_ZZ11blockToJSONRN4node12BlockManagerERK6CBlockRK11CBlockIndexS7_11TxVerbosity7uint256ENK3$_0clEvUnexecuted instantiation: blockchain.cpp:_ZZ11blockToJSONRN4node12BlockManagerERK6CBlockRK11CBlockIndexS7_11TxVerbosity7uint256ENK3$_1clEvUnexecuted instantiation: blockchain.cpp:_ZZ18CreateUTXOSnapshotRN4node11NodeContextER10ChainstateO8AutoFileRKN2fs4pathES9_ENK3$_0clEvUnexecuted instantiation: blockchain.cpp:_ZZZL16getblockfrompeervENK3$_0clERK10RPCHelpManRK14JSONRPCRequestENKUlvE_clEvUnexecuted instantiation: blockchain.cpp:_ZZZL16getblockfrompeervENK3$_0clERK10RPCHelpManRK14JSONRPCRequestENKUlvE0_clEvUnexecuted instantiation: blockchain.cpp:_ZZZL16getblockfrompeervENK3$_0clERK10RPCHelpManRK14JSONRPCRequestENKUlvE1_clEvUnexecuted instantiation: blockchain.cpp:_ZZZL10scanblocksvENK3$_0clERK10RPCHelpManRK14JSONRPCRequestENKUlvE_clEvUnexecuted instantiation: blockchain.cpp:_ZZZL12dumptxoutsetvENK3$_0clERK10RPCHelpManRK14JSONRPCRequestENKUlvE_clEvUnexecuted instantiation: blockchain.cpp:_ZZZL12dumptxoutsetvENK3$_0clERK10RPCHelpManRK14JSONRPCRequestENKUlvE0_clEvUnexecuted instantiation: mempool.cpp:_ZZZL13submitpackagevENK3$_0clERK10RPCHelpManRK14JSONRPCRequestENKUlvE_clEvUnexecuted instantiation: rawtransaction.cpp:_ZZZL17getrawtransactionvENK3$_0clERK10RPCHelpManRK14JSONRPCRequestENKUlvE_clEvUnexecuted instantiation: rawtransaction.cpp:_ZZZL17getrawtransactionvENK3$_0clERK10RPCHelpManRK14JSONRPCRequestENKUlvE0_clEvUnexecuted instantiation: validation.cpp:_ZZN10Chainstate17ActivateBestChainER20BlockValidationStateSt10shared_ptrIK6CBlockEENK3$_0clEvUnexecuted instantiation: validation.cpp:_ZZN10Chainstate17ActivateBestChainER20BlockValidationStateSt10shared_ptrIK6CBlockEENK3$_1clEvUnexecuted instantiation: validation.cpp:_ZZN10Chainstate15InvalidateBlockER20BlockValidationStateP11CBlockIndexENK3$_0clEvUnexecuted instantiation: validation.cpp:_ZZN17ChainstateManager15ProcessNewBlockERKSt10shared_ptrIK6CBlockEbbPbENK3$_0clEvUnexecuted instantiation: validation.cpp:_ZZN17ChainstateManager21LoadExternalBlockFileER8AutoFileP11FlatFilePosPSt8multimapI7uint256S2_St4lessIS5_ESaISt4pairIKS5_S2_EEEENK3$_0clEvUnexecuted instantiation: validation.cpp:_ZZN17ChainstateManager16ActivateSnapshotER8AutoFileRKN4node16SnapshotMetadataEbENK3$_1clEvUnexecuted instantiation: validation.cpp:_ZZN17ChainstateManager27PopulateAndValidateSnapshotER10ChainstateR8AutoFileRKN4node16SnapshotMetadataEENK3$_1clEvUnexecuted instantiation: validation.cpp:_ZZN17ChainstateManager27PopulateAndValidateSnapshotER10ChainstateR8AutoFileRKN4node16SnapshotMetadataEENK3$_2clEvUnexecuted instantiation: validation.cpp:_ZZN17ChainstateManager27PopulateAndValidateSnapshotER10ChainstateR8AutoFileRKN4node16SnapshotMetadataEENK3$_3clEvUnexecuted instantiation: validation.cpp:_ZZN17ChainstateManager27PopulateAndValidateSnapshotER10ChainstateR8AutoFileRKN4node16SnapshotMetadataEENK3$_4clEvUnexecuted instantiation: validation.cpp:_ZZN17ChainstateManager27PopulateAndValidateSnapshotER10ChainstateR8AutoFileRKN4node16SnapshotMetadataEENK3$_5clEv_ZZN11CCheckQueueI12CScriptCheckSt4pairI13ScriptError_tNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEED1EvENKUlvE_clEv| Line | Count | Source |  | 290 | 1 | #define WITH_LOCK(cs, code) (MaybeCheckNotHeld(cs), [&]() -> decltype(auto) { LOCK(cs); code; }()) | 
Unexecuted instantiation: base.cpp:_ZZN9BaseIndex4InitEvENK3$_0clEvUnexecuted instantiation: base.cpp:_ZZN9BaseIndex4SyncEvENK3$_0clEvUnexecuted instantiation: base.cpp:_ZZN9BaseIndex17SetBestBlockIndexEPK11CBlockIndexENK3$_0clEv | 
| 291 |  |  | 
| 292 |  | #endif // BITCOIN_SYNC_H |