LLVM API Documentation

UniqueLock.h
Go to the documentation of this file.
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