SharedCluster.h revision 296417
1254721Semaste//===------------------SharedCluster.h --------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#ifndef utility_SharedCluster_h_ 11254721Semaste#define utility_SharedCluster_h_ 12254721Semaste 13254721Semaste#include "lldb/Utility/SharingPtr.h" 14254721Semaste#include "lldb/Host/Mutex.h" 15254721Semaste 16276479Sdim#include "llvm/ADT/SmallPtrSet.h" 17276479Sdim 18254721Semastenamespace lldb_private { 19254721Semaste 20254721Semastenamespace imp 21254721Semaste{ 22254721Semaste template <typename T> 23254721Semaste class shared_ptr_refcount : public lldb_private::imp::shared_count 24254721Semaste { 25254721Semaste public: 26254721Semaste template<class Y> shared_ptr_refcount (Y *in) : shared_count (0), manager(in) {} 27254721Semaste 28254721Semaste shared_ptr_refcount() : shared_count (0) {} 29254721Semaste 30296417Sdim ~shared_ptr_refcount() override 31254721Semaste { 32254721Semaste } 33254721Semaste 34296417Sdim void on_zero_shared() override 35254721Semaste { 36254721Semaste manager->DecrementRefCount(); 37254721Semaste } 38296417Sdim 39254721Semaste private: 40254721Semaste T *manager; 41254721Semaste }; 42254721Semaste 43254721Semaste} // namespace imp 44254721Semaste 45254721Semastetemplate <class T> 46254721Semasteclass ClusterManager 47254721Semaste{ 48254721Semastepublic: 49254721Semaste ClusterManager () : 50254721Semaste m_objects(), 51254721Semaste m_external_ref(0), 52254721Semaste m_mutex(Mutex::eMutexTypeNormal) {} 53254721Semaste 54254721Semaste ~ClusterManager () 55254721Semaste { 56276479Sdim for (typename llvm::SmallPtrSet<T *, 16>::iterator pos = m_objects.begin(), end = m_objects.end(); pos != end; ++pos) 57254721Semaste { 58276479Sdim T *object = *pos; 59276479Sdim delete object; 60254721Semaste } 61276479Sdim 62254721Semaste // Decrement refcount should have been called on this ClusterManager, 63254721Semaste // and it should have locked the mutex, now we will unlock it before 64254721Semaste // we destroy it... 65254721Semaste m_mutex.Unlock(); 66254721Semaste } 67254721Semaste 68254721Semaste void ManageObject (T *new_object) 69254721Semaste { 70254721Semaste Mutex::Locker locker (m_mutex); 71276479Sdim m_objects.insert (new_object); 72254721Semaste } 73254721Semaste 74254721Semaste typename lldb_private::SharingPtr<T> GetSharedPointer(T *desired_object) 75254721Semaste { 76254721Semaste { 77254721Semaste Mutex::Locker locker (m_mutex); 78254721Semaste m_external_ref++; 79276479Sdim assert (m_objects.count(desired_object)); 80254721Semaste } 81254721Semaste return typename lldb_private::SharingPtr<T> (desired_object, new imp::shared_ptr_refcount<ClusterManager> (this)); 82254721Semaste } 83254721Semaste 84254721Semasteprivate: 85254721Semaste 86254721Semaste void DecrementRefCount () 87254721Semaste { 88254721Semaste m_mutex.Lock(); 89254721Semaste m_external_ref--; 90254721Semaste if (m_external_ref == 0) 91254721Semaste delete this; 92254721Semaste else 93254721Semaste m_mutex.Unlock(); 94254721Semaste } 95254721Semaste 96254721Semaste friend class imp::shared_ptr_refcount<ClusterManager>; 97254721Semaste 98276479Sdim llvm::SmallPtrSet<T *, 16> m_objects; 99254721Semaste int m_external_ref; 100254721Semaste Mutex m_mutex; 101254721Semaste}; 102254721Semaste 103254721Semaste} // namespace lldb_private 104296417Sdim 105254721Semaste#endif // utility_SharedCluster_h_ 106