SharedCluster.h revision 314564
1//===------------------SharedCluster.h --------------------------*- 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#ifndef utility_SharedCluster_h_ 11#define utility_SharedCluster_h_ 12 13#include "lldb/Utility/LLDBAssert.h" 14#include "lldb/Utility/SharingPtr.h" 15 16#include "llvm/ADT/SmallPtrSet.h" 17 18namespace lldb_private { 19 20namespace imp { 21template <typename T> 22class shared_ptr_refcount : public lldb_private::imp::shared_count { 23public: 24 template <class Y> 25 shared_ptr_refcount(Y *in) : shared_count(0), manager(in) {} 26 27 shared_ptr_refcount() : shared_count(0) {} 28 29 ~shared_ptr_refcount() override {} 30 31 void on_zero_shared() override { manager->DecrementRefCount(); } 32 33private: 34 T *manager; 35}; 36 37} // namespace imp 38 39template <class T> class ClusterManager { 40public: 41 ClusterManager() : m_objects(), m_external_ref(0), m_mutex() {} 42 43 ~ClusterManager() { 44 for (typename llvm::SmallPtrSet<T *, 16>::iterator pos = m_objects.begin(), 45 end = m_objects.end(); 46 pos != end; ++pos) { 47 T *object = *pos; 48 delete object; 49 } 50 51 // Decrement refcount should have been called on this ClusterManager, 52 // and it should have locked the mutex, now we will unlock it before 53 // we destroy it... 54 m_mutex.unlock(); 55 } 56 57 void ManageObject(T *new_object) { 58 std::lock_guard<std::mutex> guard(m_mutex); 59 m_objects.insert(new_object); 60 } 61 62 typename lldb_private::SharingPtr<T> GetSharedPointer(T *desired_object) { 63 { 64 std::lock_guard<std::mutex> guard(m_mutex); 65 m_external_ref++; 66 if (0 == m_objects.count(desired_object)) { 67 lldbassert(false && "object not found in shared cluster when expected"); 68 desired_object = nullptr; 69 } 70 } 71 return typename lldb_private::SharingPtr<T>( 72 desired_object, new imp::shared_ptr_refcount<ClusterManager>(this)); 73 } 74 75private: 76 void DecrementRefCount() { 77 m_mutex.lock(); 78 m_external_ref--; 79 if (m_external_ref == 0) 80 delete this; 81 else 82 m_mutex.unlock(); 83 } 84 85 friend class imp::shared_ptr_refcount<ClusterManager>; 86 87 llvm::SmallPtrSet<T *, 16> m_objects; 88 int m_external_ref; 89 std::mutex m_mutex; 90}; 91 92} // namespace lldb_private 93 94#endif // utility_SharedCluster_h_ 95