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 LLDB_UTILITY_SHAREDCLUSTER_H 10 #define LLDB_UTILITY_SHAREDCLUSTER_H 11 12 #include "lldb/Utility/LLDBAssert.h" 13 #include "llvm/ADT/STLExtras.h" 14 #include "llvm/ADT/SmallPtrSet.h" 15 16 #include <memory> 17 #include <mutex> 18 19 namespace lldb_private { 20 21 template <class T> 22 class ClusterManager : public std::enable_shared_from_this<ClusterManager<T>> { 23 public: Create()24 static std::shared_ptr<ClusterManager> Create() { 25 return std::shared_ptr<ClusterManager>(new ClusterManager()); 26 } 27 ~ClusterManager()28 ~ClusterManager() { 29 for (T *obj : m_objects) 30 delete obj; 31 } 32 ManageObject(T * new_object)33 void ManageObject(T *new_object) { 34 std::lock_guard<std::mutex> guard(m_mutex); 35 auto ret = m_objects.insert(new_object); 36 assert(ret.second && "ManageObject called twice for the same object?"); 37 (void)ret; 38 } 39 GetSharedPointer(T * desired_object)40 std::shared_ptr<T> GetSharedPointer(T *desired_object) { 41 std::lock_guard<std::mutex> guard(m_mutex); 42 auto this_sp = this->shared_from_this(); 43 size_t count = m_objects.count(desired_object); 44 if (count == 0) { 45 lldbassert(false && "object not found in shared cluster when expected"); 46 desired_object = nullptr; 47 } 48 return {std::move(this_sp), desired_object}; 49 } 50 51 private: ClusterManager()52 ClusterManager() : m_objects() {} 53 // The cluster manager is used primarily to manage the 54 // children of root ValueObjects. So it will always have 55 // one element - the root. Pointers will often have dynamic 56 // values, so having 2 entries is pretty common. It's also 57 // pretty common to have small (2,3) structs, so setting the 58 // static size to 4 will cover those cases with no allocations 59 // w/o wasting too much space. 60 llvm::SmallPtrSet<T *, 4> m_objects; 61 std::mutex m_mutex; 62 }; 63 64 } // namespace lldb_private 65 66 #endif // LLDB_UTILITY_SHAREDCLUSTER_H 67