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