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