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 namespace lldb_private { 17 18 namespace imp 19 { 20 template <typename T> 21 class shared_ptr_refcount : public lldb_private::imp::shared_count 22 { 23 public: shared_ptr_refcount(Y * in)24 template<class Y> shared_ptr_refcount (Y *in) : shared_count (0), manager(in) {} 25 shared_ptr_refcount()26 shared_ptr_refcount() : shared_count (0) {} 27 ~shared_ptr_refcount()28 virtual ~shared_ptr_refcount () 29 { 30 } 31 on_zero_shared()32 virtual void on_zero_shared () 33 { 34 manager->DecrementRefCount(); 35 } 36 private: 37 T *manager; 38 }; 39 40 } // namespace imp 41 42 template <class T> 43 class ClusterManager 44 { 45 public: ClusterManager()46 ClusterManager () : 47 m_objects(), 48 m_external_ref(0), 49 m_mutex(Mutex::eMutexTypeNormal) {} 50 ~ClusterManager()51 ~ClusterManager () 52 { 53 size_t n_items = m_objects.size(); 54 for (size_t i = 0; i < n_items; i++) 55 { 56 delete m_objects[i]; 57 } 58 // Decrement refcount should have been called on this ClusterManager, 59 // and it should have locked the mutex, now we will unlock it before 60 // we destroy it... 61 m_mutex.Unlock(); 62 } 63 ManageObject(T * new_object)64 void ManageObject (T *new_object) 65 { 66 Mutex::Locker locker (m_mutex); 67 if (!ContainsObject(new_object)) 68 m_objects.push_back (new_object); 69 } 70 GetSharedPointer(T * desired_object)71 typename lldb_private::SharingPtr<T> GetSharedPointer(T *desired_object) 72 { 73 { 74 Mutex::Locker locker (m_mutex); 75 m_external_ref++; 76 assert (ContainsObject(desired_object)); 77 } 78 return typename lldb_private::SharingPtr<T> (desired_object, new imp::shared_ptr_refcount<ClusterManager> (this)); 79 } 80 81 private: 82 ContainsObject(const T * desired_object)83 bool ContainsObject (const T *desired_object) 84 { 85 typename std::vector<T *>::iterator pos, end = m_objects.end(); 86 pos = std::find(m_objects.begin(), end, desired_object); 87 return pos != end; 88 } 89 DecrementRefCount()90 void 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 std::vector<T *> m_objects; 103 int m_external_ref; 104 Mutex m_mutex; 105 }; 106 107 } // namespace lldb_private 108 #endif // utility_SharedCluster_h_ 109