//===------------------SharedCluster.h --------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef utility_SharedCluster_h_ #define utility_SharedCluster_h_ #include "lldb/Utility/SharingPtr.h" #include "lldb/Host/Mutex.h" namespace lldb_private { namespace imp { template class shared_ptr_refcount : public lldb_private::imp::shared_count { public: template shared_ptr_refcount (Y *in) : shared_count (0), manager(in) {} shared_ptr_refcount() : shared_count (0) {} virtual ~shared_ptr_refcount () { } virtual void on_zero_shared () { manager->DecrementRefCount(); } private: T *manager; }; } // namespace imp template class ClusterManager { public: ClusterManager () : m_objects(), m_external_ref(0), m_mutex(Mutex::eMutexTypeNormal) {} ~ClusterManager () { size_t n_items = m_objects.size(); for (size_t i = 0; i < n_items; i++) { delete m_objects[i]; } // Decrement refcount should have been called on this ClusterManager, // and it should have locked the mutex, now we will unlock it before // we destroy it... m_mutex.Unlock(); } void ManageObject (T *new_object) { Mutex::Locker locker (m_mutex); if (!ContainsObject(new_object)) m_objects.push_back (new_object); } typename lldb_private::SharingPtr GetSharedPointer(T *desired_object) { { Mutex::Locker locker (m_mutex); m_external_ref++; assert (ContainsObject(desired_object)); } return typename lldb_private::SharingPtr (desired_object, new imp::shared_ptr_refcount (this)); } private: bool ContainsObject (const T *desired_object) { typename std::vector::iterator pos, end = m_objects.end(); pos = std::find(m_objects.begin(), end, desired_object); return pos != end; } void DecrementRefCount () { m_mutex.Lock(); m_external_ref--; if (m_external_ref == 0) delete this; else m_mutex.Unlock(); } friend class imp::shared_ptr_refcount; std::vector m_objects; int m_external_ref; Mutex m_mutex; }; } // namespace lldb_private #endif // utility_SharedCluster_h_