diff options
Diffstat (limited to 'include/llvm/ADT/IntrusiveRefCntPtr.h')
-rw-r--r-- | include/llvm/ADT/IntrusiveRefCntPtr.h | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h index b8b8861..729e37f 100644 --- a/include/llvm/ADT/IntrusiveRefCntPtr.h +++ b/include/llvm/ADT/IntrusiveRefCntPtr.h @@ -23,6 +23,7 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" +#include <atomic> #include <memory> namespace llvm { @@ -88,6 +89,31 @@ namespace llvm { static void retain(T *obj) { obj->Retain(); } static void release(T *obj) { obj->Release(); } }; + +/// \brief A thread-safe version of \c llvm::RefCountedBase. +/// +/// A generic base class for objects that wish to have their lifetimes managed +/// using reference counts. Classes subclass \c ThreadSafeRefCountedBase to +/// obtain such functionality, and are typically handled with +/// \c IntrusiveRefCntPtr "smart pointers" which automatically handle the +/// management of reference counts. +template <class Derived> +class ThreadSafeRefCountedBase { + mutable std::atomic<int> RefCount; + +protected: + ThreadSafeRefCountedBase() : RefCount(0) {} + +public: + void Retain() const { ++RefCount; } + + void Release() const { + int NewRefCount = --RefCount; + assert(NewRefCount >= 0 && "Reference count was already zero."); + if (NewRefCount == 0) + delete static_cast<const Derived*>(this); + } +}; //===----------------------------------------------------------------------===// /// IntrusiveRefCntPtr - A template class that implements a "smart pointer" @@ -109,7 +135,7 @@ namespace llvm { template <typename T> class IntrusiveRefCntPtr { T* Obj; - typedef IntrusiveRefCntPtr this_type; + public: typedef T element_type; @@ -123,7 +149,6 @@ namespace llvm { retain(); } -#if LLVM_HAS_RVALUE_REFERENCES IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) { S.Obj = 0; } @@ -132,7 +157,6 @@ namespace llvm { IntrusiveRefCntPtr(IntrusiveRefCntPtr<X>&& S) : Obj(S.getPtr()) { S.Obj = 0; } -#endif template <class X> IntrusiveRefCntPtr(const IntrusiveRefCntPtr<X>& S) |