]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/include/lldb/Utility/SharedCluster.h
Move all sources from the llvm project into contrib/llvm-project.
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / include / lldb / Utility / SharedCluster.h
1 //===------------------SharedCluster.h --------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef utility_SharedCluster_h_
10 #define utility_SharedCluster_h_
11
12 #include "lldb/Utility/LLDBAssert.h"
13 #include "lldb/Utility/SharingPtr.h"
14
15 #include "llvm/ADT/SmallPtrSet.h"
16
17 #include <mutex>
18
19 namespace lldb_private {
20
21 namespace imp {
22 template <typename T>
23 class shared_ptr_refcount : public lldb_private::imp::shared_count {
24 public:
25   template <class Y>
26   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   void on_zero_shared() override { manager->DecrementRefCount(); }
33
34 private:
35   T *manager;
36 };
37
38 } // namespace imp
39
40 template <class T> class ClusterManager {
41 public:
42   ClusterManager() : m_objects(), m_external_ref(0), m_mutex() {}
43
44   ~ClusterManager() {
45     for (typename llvm::SmallPtrSet<T *, 16>::iterator pos = m_objects.begin(),
46                                                        end = m_objects.end();
47          pos != end; ++pos) {
48       T *object = *pos;
49       delete object;
50     }
51
52     // Decrement refcount should have been called on this ClusterManager, and
53     // it should have locked the mutex, now we will unlock it before we destroy
54     // it...
55     m_mutex.unlock();
56   }
57
58   void ManageObject(T *new_object) {
59     std::lock_guard<std::mutex> guard(m_mutex);
60     m_objects.insert(new_object);
61   }
62
63   typename lldb_private::SharingPtr<T> GetSharedPointer(T *desired_object) {
64     {
65       std::lock_guard<std::mutex> guard(m_mutex);
66       m_external_ref++;
67       if (0 == m_objects.count(desired_object)) {
68         lldbassert(false && "object not found in shared cluster when expected");
69         desired_object = nullptr;
70       }
71     }
72     return typename lldb_private::SharingPtr<T>(
73         desired_object, new imp::shared_ptr_refcount<ClusterManager>(this));
74   }
75
76 private:
77   void DecrementRefCount() {
78     m_mutex.lock();
79     m_external_ref--;
80     if (m_external_ref == 0)
81       delete this;
82     else
83       m_mutex.unlock();
84   }
85
86   friend class imp::shared_ptr_refcount<ClusterManager>;
87
88   llvm::SmallPtrSet<T *, 16> m_objects;
89   int m_external_ref;
90   std::mutex m_mutex;
91 };
92
93 } // namespace lldb_private
94
95 #endif // utility_SharedCluster_h_