]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/include/lldb/Utility/SharedCluster.h
Merge clang 7.0.1 and several follow-up changes
[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/LLDBAssert.h"
14 #include "lldb/Utility/SharingPtr.h"
15
16 #include "llvm/ADT/SmallPtrSet.h"
17
18 #include <mutex>
19
20 namespace lldb_private {
21
22 namespace imp {
23 template <typename T>
24 class shared_ptr_refcount : public lldb_private::imp::shared_count {
25 public:
26   template <class Y>
27   shared_ptr_refcount(Y *in) : shared_count(0), manager(in) {}
28
29   shared_ptr_refcount() : shared_count(0) {}
30
31   ~shared_ptr_refcount() override {}
32
33   void on_zero_shared() override { manager->DecrementRefCount(); }
34
35 private:
36   T *manager;
37 };
38
39 } // namespace imp
40
41 template <class T> class ClusterManager {
42 public:
43   ClusterManager() : m_objects(), m_external_ref(0), m_mutex() {}
44
45   ~ClusterManager() {
46     for (typename llvm::SmallPtrSet<T *, 16>::iterator pos = m_objects.begin(),
47                                                        end = m_objects.end();
48          pos != end; ++pos) {
49       T *object = *pos;
50       delete object;
51     }
52
53     // Decrement refcount should have been called on this ClusterManager, and
54     // it should have locked the mutex, now we will unlock it before we destroy
55     // it...
56     m_mutex.unlock();
57   }
58
59   void ManageObject(T *new_object) {
60     std::lock_guard<std::mutex> guard(m_mutex);
61     m_objects.insert(new_object);
62   }
63
64   typename lldb_private::SharingPtr<T> GetSharedPointer(T *desired_object) {
65     {
66       std::lock_guard<std::mutex> guard(m_mutex);
67       m_external_ref++;
68       if (0 == m_objects.count(desired_object)) {
69         lldbassert(false && "object not found in shared cluster when expected");
70         desired_object = nullptr;
71       }
72     }
73     return typename lldb_private::SharingPtr<T>(
74         desired_object, new imp::shared_ptr_refcount<ClusterManager>(this));
75   }
76
77 private:
78   void DecrementRefCount() {
79     m_mutex.lock();
80     m_external_ref--;
81     if (m_external_ref == 0)
82       delete this;
83     else
84       m_mutex.unlock();
85   }
86
87   friend class imp::shared_ptr_refcount<ClusterManager>;
88
89   llvm::SmallPtrSet<T *, 16> m_objects;
90   int m_external_ref;
91   std::mutex m_mutex;
92 };
93
94 } // namespace lldb_private
95
96 #endif // utility_SharedCluster_h_