]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/lldb/Utility/SharedCluster.h
Vendor import of lldb release_39 branch r276489:
[FreeBSD/FreeBSD.git] / 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/LLDBAssert.h"
14 #include "lldb/Utility/SharingPtr.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() : m_objects(), m_external_ref(0), m_mutex() {}
50
51     ~ClusterManager()
52     {
53         for (typename llvm::SmallPtrSet<T *, 16>::iterator pos = m_objects.begin(), end = m_objects.end(); pos != end;
54              ++pos)
55         {
56             T *object = *pos;
57             delete object;
58         }
59
60         // Decrement refcount should have been called on this ClusterManager,
61         // and it should have locked the mutex, now we will unlock it before
62         // we destroy it...
63         m_mutex.unlock();
64     }
65
66     void
67     ManageObject(T *new_object)
68     {
69         std::lock_guard<std::mutex> guard(m_mutex);
70         m_objects.insert(new_object);
71     }
72
73     typename lldb_private::SharingPtr<T>
74     GetSharedPointer(T *desired_object)
75     {
76         {
77             std::lock_guard<std::mutex> guard(m_mutex);
78             m_external_ref++;
79             if (0 == m_objects.count(desired_object))
80             {
81                 lldbassert(false && "object not found in shared cluster when expected");
82                 desired_object = nullptr;
83             }
84         }
85         return typename lldb_private::SharingPtr<T>(desired_object, new imp::shared_ptr_refcount<ClusterManager>(this));
86     }
87
88 private:
89     void
90     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     llvm::SmallPtrSet<T *, 16> m_objects;
103     int m_external_ref;
104     std::mutex m_mutex;
105 };
106
107 } // namespace lldb_private
108
109 #endif // utility_SharedCluster_h_