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 20namespace 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