Home | History | Annotate | Download | only in Utility
      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:
     24         template<class Y> shared_ptr_refcount (Y *in) : shared_count (0), manager(in) {}
     25 
     26         shared_ptr_refcount() : shared_count (0) {}
     27 
     28         virtual ~shared_ptr_refcount ()
     29         {
     30         }
     31 
     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:
     46     ClusterManager () :
     47         m_objects(),
     48         m_external_ref(0),
     49         m_mutex(Mutex::eMutexTypeNormal) {}
     50 
     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 
     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 
     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 
     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 
     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