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