/ src / util / stdmutex.h
stdmutex.h
 1  // Copyright (c) 2009-2010 Satoshi Nakamoto
 2  // Copyright (c) 2009-present 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_UTIL_STDMUTEX_H
 7  #define BITCOIN_UTIL_STDMUTEX_H
 8  
 9  // This header declares threading primitives compatible with Clang
10  // Thread Safety Analysis and provides appropriate annotation macros.
11  #include <threadsafety.h> // IWYU pragma: export
12  
13  #include <util/macros.h>
14  
15  #include <mutex>
16  
17  // StdMutex provides an annotated version of std::mutex for us,
18  // and should only be used when sync.h Mutex/LOCK/etc are not usable.
19  class LOCKABLE StdMutex : public std::mutex
20  {
21  public:
22  #ifdef __clang__
23      //! For negative capabilities in the Clang Thread Safety Analysis.
24      //! A negative requirement uses the EXCLUSIVE_LOCKS_REQUIRED attribute, in conjunction
25      //! with the ! operator, to indicate that a mutex should not be held.
26      const StdMutex& operator!() const { return *this; }
27  #endif // __clang__
28  
29      // StdMutex::Guard provides an annotated version of std::lock_guard for us.
30      class SCOPED_LOCKABLE Guard : public std::lock_guard<StdMutex>
31      {
32      public:
33          explicit Guard(StdMutex& cs) EXCLUSIVE_LOCK_FUNCTION(cs) : std::lock_guard<StdMutex>(cs) {}
34          ~Guard() UNLOCK_FUNCTION() = default;
35      };
36  
37      static inline StdMutex& CheckNotHeld(StdMutex& cs) EXCLUSIVE_LOCKS_REQUIRED(!cs) LOCK_RETURNED(cs) { return cs; }
38  };
39  
40  // Provide STDLOCK(..) wrapper around StdMutex::Guard that checks the lock is not already held
41  #define STDLOCK(cs) StdMutex::Guard UNIQUE_NAME(criticalblock){StdMutex::CheckNotHeld(cs)}
42  
43  using StdLockGuard = StdMutex::Guard; // TODO: remove, provided for backwards compat only
44  
45  #endif // BITCOIN_UTIL_STDMUTEX_H