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