SharedCluster.h revision 296417
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/SharingPtr.h" 14#include "lldb/Host/Mutex.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 () : 50 m_objects(), 51 m_external_ref(0), 52 m_mutex(Mutex::eMutexTypeNormal) {} 53 54 ~ClusterManager () 55 { 56 for (typename llvm::SmallPtrSet<T *, 16>::iterator pos = m_objects.begin(), end = m_objects.end(); pos != end; ++pos) 57 { 58 T *object = *pos; 59 delete object; 60 } 61 62 // Decrement refcount should have been called on this ClusterManager, 63 // and it should have locked the mutex, now we will unlock it before 64 // we destroy it... 65 m_mutex.Unlock(); 66 } 67 68 void ManageObject (T *new_object) 69 { 70 Mutex::Locker locker (m_mutex); 71 m_objects.insert (new_object); 72 } 73 74 typename lldb_private::SharingPtr<T> GetSharedPointer(T *desired_object) 75 { 76 { 77 Mutex::Locker locker (m_mutex); 78 m_external_ref++; 79 assert (m_objects.count(desired_object)); 80 } 81 return typename lldb_private::SharingPtr<T> (desired_object, new imp::shared_ptr_refcount<ClusterManager> (this)); 82 } 83 84private: 85 86 void DecrementRefCount () 87 { 88 m_mutex.Lock(); 89 m_external_ref--; 90 if (m_external_ref == 0) 91 delete this; 92 else 93 m_mutex.Unlock(); 94 } 95 96 friend class imp::shared_ptr_refcount<ClusterManager>; 97 98 llvm::SmallPtrSet<T *, 16> m_objects; 99 int m_external_ref; 100 Mutex m_mutex; 101}; 102 103} // namespace lldb_private 104 105#endif // utility_SharedCluster_h_ 106