LLVM API Documentation
00001 //===-- Support/UniqueLock.h - Acquire/Release Mutex In Scope ---*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines a guard for a block of code that ensures a Mutex is locked 00011 // upon construction and released upon destruction. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_SUPPORT_UNIQUE_LOCK_H 00016 #define LLVM_SUPPORT_UNIQUE_LOCK_H 00017 00018 #include "llvm/Support/Mutex.h" 00019 00020 namespace llvm { 00021 /// A pared-down imitation of std::unique_lock from C++11. Contrary to the 00022 /// name, it's really more of a wrapper for a lock. It may or may not have 00023 /// an associated mutex, which is guaranteed to be locked upon creation 00024 /// and unlocked after destruction. unique_lock can also unlock the mutex 00025 /// and re-lock it freely during its lifetime. 00026 /// @brief Guard a section of code with a mutex. 00027 template<typename MutexT> 00028 class unique_lock { 00029 MutexT *M; 00030 bool locked; 00031 00032 unique_lock(const unique_lock &) LLVM_DELETED_FUNCTION; 00033 void operator=(const unique_lock &) LLVM_DELETED_FUNCTION; 00034 public: 00035 unique_lock() : M(nullptr), locked(false) {} 00036 explicit unique_lock(MutexT &m) : M(&m), locked(true) { M->lock(); } 00037 00038 void operator=(unique_lock &&o) { 00039 if (owns_lock()) 00040 M->unlock(); 00041 M = o.M; 00042 locked = o.locked; 00043 o.M = nullptr; 00044 o.locked = false; 00045 } 00046 00047 ~unique_lock() { if (owns_lock()) M->unlock(); } 00048 00049 void lock() { 00050 assert(!locked && "mutex already locked!"); 00051 assert(M && "no associated mutex!"); 00052 M->lock(); 00053 locked = true; 00054 } 00055 00056 void unlock() { 00057 assert(locked && "unlocking a mutex that isn't locked!"); 00058 assert(M && "no associated mutex!"); 00059 M->unlock(); 00060 locked = false; 00061 } 00062 00063 bool owns_lock() { return locked; } 00064 }; 00065 } 00066 00067 #endif // LLVM_SUPPORT_UNIQUE_LOCK_H