Home | History | Annotate | Download | only in Support
      1 //===-- Support/UniqueLock.h - Acquire/Release Mutex In Scope ---*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines a guard for a block of code that ensures a Mutex is locked
     11 // upon construction and released upon destruction.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_SUPPORT_UNIQUE_LOCK_H
     16 #define LLVM_SUPPORT_UNIQUE_LOCK_H
     17 
     18 #include "llvm/Support/Mutex.h"
     19 
     20 namespace llvm {
     21   /// A pared-down imitation of std::unique_lock from C++11. Contrary to the
     22   /// name, it's really more of a wrapper for a lock. It may or may not have
     23   /// an associated mutex, which is guaranteed to be locked upon creation
     24   /// and unlocked after destruction. unique_lock can also unlock the mutex
     25   /// and re-lock it freely during its lifetime.
     26   /// @brief Guard a section of code with a mutex.
     27   template<typename MutexT>
     28   class unique_lock {
     29     MutexT *M;
     30     bool locked;
     31 
     32     unique_lock(const unique_lock &) = delete;
     33     void operator=(const unique_lock &) = delete;
     34   public:
     35     unique_lock() : M(nullptr), locked(false) {}
     36     explicit unique_lock(MutexT &m) : M(&m), locked(true) { M->lock(); }
     37 
     38     void operator=(unique_lock &&o) {
     39       if (owns_lock())
     40         M->unlock();
     41       M = o.M;
     42       locked = o.locked;
     43       o.M = nullptr;
     44       o.locked = false;
     45     }
     46 
     47     ~unique_lock() { if (owns_lock()) M->unlock(); }
     48 
     49     void lock() {
     50       assert(!locked && "mutex already locked!");
     51       assert(M && "no associated mutex!");
     52       M->lock();
     53       locked = true;
     54     }
     55 
     56     void unlock() {
     57       assert(locked && "unlocking a mutex that isn't locked!");
     58       assert(M && "no associated mutex!");
     59       M->unlock();
     60       locked = false;
     61     }
     62 
     63     bool owns_lock() { return locked; }
     64   };
     65 }
     66 
     67 #endif // LLVM_SUPPORT_UNIQUE_LOCK_H
     68