|  | //===-- Support/UniqueLock.h - Acquire/Release Mutex In Scope ---*- C++ -*-===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // This file defines a guard for a block of code that ensures a Mutex is locked | 
|  | // upon construction and released upon destruction. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #ifndef LLVM_SUPPORT_UNIQUE_LOCK_H | 
|  | #define LLVM_SUPPORT_UNIQUE_LOCK_H | 
|  |  | 
|  | #include "llvm/Support/Mutex.h" | 
|  |  | 
|  | namespace llvm { | 
|  | /// A pared-down imitation of std::unique_lock from C++11. Contrary to the | 
|  | /// name, it's really more of a wrapper for a lock. It may or may not have | 
|  | /// an associated mutex, which is guaranteed to be locked upon creation | 
|  | /// and unlocked after destruction. unique_lock can also unlock the mutex | 
|  | /// and re-lock it freely during its lifetime. | 
|  | /// @brief Guard a section of code with a mutex. | 
|  | template<typename MutexT> | 
|  | class unique_lock { | 
|  | MutexT *M; | 
|  | bool locked; | 
|  |  | 
|  | unique_lock(const unique_lock &) = delete; | 
|  | void operator=(const unique_lock &) = delete; | 
|  | public: | 
|  | unique_lock() : M(nullptr), locked(false) {} | 
|  | explicit unique_lock(MutexT &m) : M(&m), locked(true) { M->lock(); } | 
|  |  | 
|  | void operator=(unique_lock &&o) { | 
|  | if (owns_lock()) | 
|  | M->unlock(); | 
|  | M = o.M; | 
|  | locked = o.locked; | 
|  | o.M = nullptr; | 
|  | o.locked = false; | 
|  | } | 
|  |  | 
|  | ~unique_lock() { if (owns_lock()) M->unlock(); } | 
|  |  | 
|  | void lock() { | 
|  | assert(!locked && "mutex already locked!"); | 
|  | assert(M && "no associated mutex!"); | 
|  | M->lock(); | 
|  | locked = true; | 
|  | } | 
|  |  | 
|  | void unlock() { | 
|  | assert(locked && "unlocking a mutex that isn't locked!"); | 
|  | assert(M && "no associated mutex!"); | 
|  | M->unlock(); | 
|  | locked = false; | 
|  | } | 
|  |  | 
|  | bool owns_lock() { return locked; } | 
|  | }; | 
|  | } | 
|  |  | 
|  | #endif // LLVM_SUPPORT_UNIQUE_LOCK_H |