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 // C Includes 14 // C++ Includes 15 #include <map> 16 17 // Other libraries and framework includes 18 // Project includes 19 #include "lldb/lldb-defines.h" 20 #include "lldb/Host/Mutex.h" 21 22 namespace lldb_private { 23 24 template <typename _Key, typename _Tp> 25 class ThreadSafeSTLMap 26 { 27 public: 28 typedef std::map<_Key,_Tp> collection; 29 typedef typename collection::iterator iterator; 30 typedef typename collection::const_iterator const_iterator; 31 //------------------------------------------------------------------ 32 // Constructors and Destructors 33 //------------------------------------------------------------------ ThreadSafeSTLMap()34 ThreadSafeSTLMap() : 35 m_collection (), 36 m_mutex (Mutex::eMutexTypeRecursive) 37 { 38 } 39 ~ThreadSafeSTLMap()40 ~ThreadSafeSTLMap() 41 { 42 } 43 44 bool IsEmpty()45 IsEmpty() const 46 { 47 Mutex::Locker locker(m_mutex); 48 return m_collection.empty(); 49 } 50 51 void Clear()52 Clear() 53 { 54 Mutex::Locker locker(m_mutex); 55 return m_collection.clear(); 56 } 57 58 size_t Erase(const _Key & key)59 Erase (const _Key& key) 60 { 61 Mutex::Locker locker(m_mutex); 62 return EraseNoLock (key); 63 } 64 65 size_t EraseNoLock(const _Key & key)66 EraseNoLock (const _Key& key) 67 { 68 return m_collection.erase (key); 69 } 70 71 bool GetValueForKey(const _Key & key,_Tp & value)72 GetValueForKey (const _Key& key, _Tp &value) const 73 { 74 Mutex::Locker locker(m_mutex); 75 return GetValueForKeyNoLock (key, value); 76 } 77 78 // Call this if you have already manually locked the mutex using the 79 // GetMutex() accessor 80 bool GetValueForKeyNoLock(const _Key & key,_Tp & value)81 GetValueForKeyNoLock (const _Key& key, _Tp &value) const 82 { 83 const_iterator pos = m_collection.find(key); 84 if (pos != m_collection.end()) 85 { 86 value = pos->second; 87 return true; 88 } 89 return false; 90 } 91 92 bool GetFirstKeyForValue(const _Tp & value,_Key & key)93 GetFirstKeyForValue (const _Tp &value, _Key& key) const 94 { 95 Mutex::Locker locker(m_mutex); 96 return GetFirstKeyForValueNoLock (value, key); 97 } 98 99 bool GetFirstKeyForValueNoLock(const _Tp & value,_Key & key)100 GetFirstKeyForValueNoLock (const _Tp &value, _Key& key) const 101 { 102 const_iterator pos, end = m_collection.end(); 103 for (pos = m_collection.begin(); pos != end; ++pos) 104 { 105 if (pos->second == value) 106 { 107 key = pos->first; 108 return true; 109 } 110 } 111 return false; 112 } 113 114 bool LowerBound(const _Key & key,_Key & match_key,_Tp & match_value,bool decrement_if_not_equal)115 LowerBound (const _Key& key, 116 _Key& match_key, 117 _Tp &match_value, 118 bool decrement_if_not_equal) const 119 { 120 Mutex::Locker locker(m_mutex); 121 return LowerBoundNoLock (key, match_key, match_value, decrement_if_not_equal); 122 } 123 124 bool LowerBoundNoLock(const _Key & key,_Key & match_key,_Tp & match_value,bool decrement_if_not_equal)125 LowerBoundNoLock (const _Key& key, 126 _Key& match_key, 127 _Tp &match_value, 128 bool decrement_if_not_equal) const 129 { 130 const_iterator pos = m_collection.lower_bound (key); 131 if (pos != m_collection.end()) 132 { 133 match_key = pos->first; 134 if (decrement_if_not_equal && key != match_key && pos != m_collection.begin()) 135 { 136 --pos; 137 match_key = pos->first; 138 } 139 match_value = pos->second; 140 return true; 141 } 142 return false; 143 } 144 145 iterator lower_bound_unsafe(const _Key & key)146 lower_bound_unsafe (const _Key& key) 147 { 148 return m_collection.lower_bound (key); 149 } 150 151 void SetValueForKey(const _Key & key,const _Tp & value)152 SetValueForKey (const _Key& key, const _Tp &value) 153 { 154 Mutex::Locker locker(m_mutex); 155 SetValueForKeyNoLock (key, value); 156 } 157 158 // Call this if you have already manually locked the mutex using the 159 // GetMutex() accessor 160 void SetValueForKeyNoLock(const _Key & key,const _Tp & value)161 SetValueForKeyNoLock (const _Key& key, const _Tp &value) 162 { 163 m_collection[key] = value; 164 } 165 166 Mutex & GetMutex()167 GetMutex () 168 { 169 return m_mutex; 170 } 171 172 private: 173 collection m_collection; 174 mutable Mutex m_mutex; 175 176 //------------------------------------------------------------------ 177 // For ThreadSafeSTLMap only 178 //------------------------------------------------------------------ 179 DISALLOW_COPY_AND_ASSIGN (ThreadSafeSTLMap); 180 }; 181 182 183 } // namespace lldb_private 184 185 #endif // liblldb_ThreadSafeSTLMap_h_ 186