1 //===-- ThreadSafeSTLMap.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 liblldb_ThreadSafeSTLMap_h_ 11 #define liblldb_ThreadSafeSTLMap_h_ 12 13 #include <map> 14 #include <mutex> 15 16 #include "lldb/lldb-defines.h" 17 18 namespace lldb_private { 19 20 template <typename _Key, typename _Tp> class ThreadSafeSTLMap { 21 public: 22 typedef std::map<_Key, _Tp> collection; 23 typedef typename collection::iterator iterator; 24 typedef typename collection::const_iterator const_iterator; 25 //------------------------------------------------------------------ 26 // Constructors and Destructors 27 //------------------------------------------------------------------ ThreadSafeSTLMap()28 ThreadSafeSTLMap() : m_collection(), m_mutex() {} 29 ~ThreadSafeSTLMap()30 ~ThreadSafeSTLMap() {} 31 IsEmpty()32 bool IsEmpty() const { 33 std::lock_guard<std::recursive_mutex> guard(m_mutex); 34 return m_collection.empty(); 35 } 36 Clear()37 void Clear() { 38 std::lock_guard<std::recursive_mutex> guard(m_mutex); 39 return m_collection.clear(); 40 } 41 Erase(const _Key & key)42 size_t Erase(const _Key &key) { 43 std::lock_guard<std::recursive_mutex> guard(m_mutex); 44 return EraseNoLock(key); 45 } 46 EraseNoLock(const _Key & key)47 size_t EraseNoLock(const _Key &key) { return m_collection.erase(key); } 48 GetValueForKey(const _Key & key,_Tp & value)49 bool GetValueForKey(const _Key &key, _Tp &value) const { 50 std::lock_guard<std::recursive_mutex> guard(m_mutex); 51 return GetValueForKeyNoLock(key, value); 52 } 53 54 // Call this if you have already manually locked the mutex using the 55 // GetMutex() accessor GetValueForKeyNoLock(const _Key & key,_Tp & value)56 bool GetValueForKeyNoLock(const _Key &key, _Tp &value) const { 57 const_iterator pos = m_collection.find(key); 58 if (pos != m_collection.end()) { 59 value = pos->second; 60 return true; 61 } 62 return false; 63 } 64 GetFirstKeyForValue(const _Tp & value,_Key & key)65 bool GetFirstKeyForValue(const _Tp &value, _Key &key) const { 66 std::lock_guard<std::recursive_mutex> guard(m_mutex); 67 return GetFirstKeyForValueNoLock(value, key); 68 } 69 GetFirstKeyForValueNoLock(const _Tp & value,_Key & key)70 bool GetFirstKeyForValueNoLock(const _Tp &value, _Key &key) const { 71 const_iterator pos, end = m_collection.end(); 72 for (pos = m_collection.begin(); pos != end; ++pos) { 73 if (pos->second == value) { 74 key = pos->first; 75 return true; 76 } 77 } 78 return false; 79 } 80 LowerBound(const _Key & key,_Key & match_key,_Tp & match_value,bool decrement_if_not_equal)81 bool LowerBound(const _Key &key, _Key &match_key, _Tp &match_value, 82 bool decrement_if_not_equal) const { 83 std::lock_guard<std::recursive_mutex> guard(m_mutex); 84 return LowerBoundNoLock(key, match_key, match_value, 85 decrement_if_not_equal); 86 } 87 LowerBoundNoLock(const _Key & key,_Key & match_key,_Tp & match_value,bool decrement_if_not_equal)88 bool LowerBoundNoLock(const _Key &key, _Key &match_key, _Tp &match_value, 89 bool decrement_if_not_equal) const { 90 const_iterator pos = m_collection.lower_bound(key); 91 if (pos != m_collection.end()) { 92 match_key = pos->first; 93 if (decrement_if_not_equal && key != match_key && 94 pos != m_collection.begin()) { 95 --pos; 96 match_key = pos->first; 97 } 98 match_value = pos->second; 99 return true; 100 } 101 return false; 102 } 103 lower_bound_unsafe(const _Key & key)104 iterator lower_bound_unsafe(const _Key &key) { 105 return m_collection.lower_bound(key); 106 } 107 SetValueForKey(const _Key & key,const _Tp & value)108 void SetValueForKey(const _Key &key, const _Tp &value) { 109 std::lock_guard<std::recursive_mutex> guard(m_mutex); 110 SetValueForKeyNoLock(key, value); 111 } 112 113 // Call this if you have already manually locked the mutex using the 114 // GetMutex() accessor SetValueForKeyNoLock(const _Key & key,const _Tp & value)115 void SetValueForKeyNoLock(const _Key &key, const _Tp &value) { 116 m_collection[key] = value; 117 } 118 GetMutex()119 std::recursive_mutex &GetMutex() { return m_mutex; } 120 121 private: 122 collection m_collection; 123 mutable std::recursive_mutex m_mutex; 124 125 //------------------------------------------------------------------ 126 // For ThreadSafeSTLMap only 127 //------------------------------------------------------------------ 128 DISALLOW_COPY_AND_ASSIGN(ThreadSafeSTLMap); 129 }; 130 131 } // namespace lldb_private 132 133 #endif // liblldb_ThreadSafeSTLMap_h_ 134