]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/lldb/include/lldb/Utility/SharedCluster.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / lldb / include / lldb / Utility / SharedCluster.h
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_