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 <cassert> 19 20 namespace llvm { 21 22 /// A pared-down imitation of std::unique_lock from C++11. Contrary to the 23 /// name, it's really more of a wrapper for a lock. It may or may not have 24 /// an associated mutex, which is guaranteed to be locked upon creation 25 /// and unlocked after destruction. unique_lock can also unlock the mutex 26 /// and re-lock it freely during its lifetime. 27 /// @brief Guard a section of code with a mutex. 28 template<typename MutexT> 29 class unique_lock { 30 MutexT *M = nullptr; 31 bool locked = false; 32 33 public: 34 unique_lock() = default; 35 explicit unique_lock(MutexT &m) : M(&m), locked(true) { M->lock(); } 36 unique_lock(const unique_lock &) = delete; 37 unique_lock &operator=(const unique_lock &) = delete; 38 39 void operator=(unique_lock &&o) { 40 if (owns_lock()) 41 M->unlock(); 42 M = o.M; 43 locked = o.locked; 44 o.M = nullptr; 45 o.locked = false; 46 } 47 48 ~unique_lock() { if (owns_lock()) M->unlock(); } 49 50 void lock() { 51 assert(!locked && "mutex already locked!"); 52 assert(M && "no associated mutex!"); 53 M->lock(); 54 locked = true; 55 } 56 57 void unlock() { 58 assert(locked && "unlocking a mutex that isn't locked!"); 59 assert(M && "no associated mutex!"); 60 M->unlock(); 61 locked = false; 62 } 63 64 bool owns_lock() { return locked; } 65 }; 66 67 } // end namespace llvm 68 69 #endif // LLVM_SUPPORT_UNIQUE_LOCK_H 70