| //===-- ThreadSafeSTLMap.h --------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef liblldb_ThreadSafeSTLMap_h_ |
| #define liblldb_ThreadSafeSTLMap_h_ |
| |
| // C Includes |
| // C++ Includes |
| #include <map> |
| #include <mutex> |
| |
| // Other libraries and framework includes |
| // Project includes |
| #include "lldb/lldb-defines.h" |
| |
| namespace lldb_private { |
| |
| template <typename _Key, typename _Tp> class ThreadSafeSTLMap { |
| public: |
| typedef std::map<_Key, _Tp> collection; |
| typedef typename collection::iterator iterator; |
| typedef typename collection::const_iterator const_iterator; |
| //------------------------------------------------------------------ |
| // Constructors and Destructors |
| //------------------------------------------------------------------ |
| ThreadSafeSTLMap() : m_collection(), m_mutex() {} |
| |
| ~ThreadSafeSTLMap() {} |
| |
| bool IsEmpty() const { |
| std::lock_guard<std::recursive_mutex> guard(m_mutex); |
| return m_collection.empty(); |
| } |
| |
| void Clear() { |
| std::lock_guard<std::recursive_mutex> guard(m_mutex); |
| return m_collection.clear(); |
| } |
| |
| size_t Erase(const _Key &key) { |
| std::lock_guard<std::recursive_mutex> guard(m_mutex); |
| return EraseNoLock(key); |
| } |
| |
| size_t EraseNoLock(const _Key &key) { return m_collection.erase(key); } |
| |
| bool GetValueForKey(const _Key &key, _Tp &value) const { |
| std::lock_guard<std::recursive_mutex> guard(m_mutex); |
| return GetValueForKeyNoLock(key, value); |
| } |
| |
| // Call this if you have already manually locked the mutex using the |
| // GetMutex() accessor |
| bool GetValueForKeyNoLock(const _Key &key, _Tp &value) const { |
| const_iterator pos = m_collection.find(key); |
| if (pos != m_collection.end()) { |
| value = pos->second; |
| return true; |
| } |
| return false; |
| } |
| |
| bool GetFirstKeyForValue(const _Tp &value, _Key &key) const { |
| std::lock_guard<std::recursive_mutex> guard(m_mutex); |
| return GetFirstKeyForValueNoLock(value, key); |
| } |
| |
| bool GetFirstKeyForValueNoLock(const _Tp &value, _Key &key) const { |
| const_iterator pos, end = m_collection.end(); |
| for (pos = m_collection.begin(); pos != end; ++pos) { |
| if (pos->second == value) { |
| key = pos->first; |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| bool LowerBound(const _Key &key, _Key &match_key, _Tp &match_value, |
| bool decrement_if_not_equal) const { |
| std::lock_guard<std::recursive_mutex> guard(m_mutex); |
| return LowerBoundNoLock(key, match_key, match_value, |
| decrement_if_not_equal); |
| } |
| |
| bool LowerBoundNoLock(const _Key &key, _Key &match_key, _Tp &match_value, |
| bool decrement_if_not_equal) const { |
| const_iterator pos = m_collection.lower_bound(key); |
| if (pos != m_collection.end()) { |
| match_key = pos->first; |
| if (decrement_if_not_equal && key != match_key && |
| pos != m_collection.begin()) { |
| --pos; |
| match_key = pos->first; |
| } |
| match_value = pos->second; |
| return true; |
| } |
| return false; |
| } |
| |
| iterator lower_bound_unsafe(const _Key &key) { |
| return m_collection.lower_bound(key); |
| } |
| |
| void SetValueForKey(const _Key &key, const _Tp &value) { |
| std::lock_guard<std::recursive_mutex> guard(m_mutex); |
| SetValueForKeyNoLock(key, value); |
| } |
| |
| // Call this if you have already manually locked the mutex using the |
| // GetMutex() accessor |
| void SetValueForKeyNoLock(const _Key &key, const _Tp &value) { |
| m_collection[key] = value; |
| } |
| |
| std::recursive_mutex &GetMutex() { return m_mutex; } |
| |
| private: |
| collection m_collection; |
| mutable std::recursive_mutex m_mutex; |
| |
| //------------------------------------------------------------------ |
| // For ThreadSafeSTLMap only |
| //------------------------------------------------------------------ |
| DISALLOW_COPY_AND_ASSIGN(ThreadSafeSTLMap); |
| }; |
| |
| } // namespace lldb_private |
| |
| #endif // liblldb_ThreadSafeSTLMap_h_ |