diff --git a/parallel_hashmap/phmap.h b/parallel_hashmap/phmap.h index 656268a..344cb0b 100644 --- a/parallel_hashmap/phmap.h +++ b/parallel_hashmap/phmap.h @@ -3805,9 +3805,18 @@ protected: mutexlock = std::move(typename Lockable::ReadWriteLock(inner)); size_t offset = set._find_key(key, hashval); if (offset == (size_t)-1) { - mutexlock.switch_to_unique(); - offset = set.prepare_insert(hashval); - return std::make_tuple(&inner, offset, true); + if (mutexlock.switch_to_unique()) { + // we did an unlock/lock, and another thread could have inserted the same key, so we need to + // do a find() again. + offset = set._find_key(key, hashval); + if (offset == (size_t)-1) { + offset = set.prepare_insert(hashval); + return std::make_tuple(&inner, offset, true); + } + } else { + offset = set.prepare_insert(hashval); + return std::make_tuple(&inner, offset, true); + } } return std::make_tuple(&inner, offset, false); } diff --git a/parallel_hashmap/phmap_base.h b/parallel_hashmap/phmap_base.h index b471481..d3c2245 100644 --- a/parallel_hashmap/phmap_base.h +++ b/parallel_hashmap/phmap_base.h @@ -4635,7 +4635,7 @@ public: void unlock() {} void lock_shared() {} void unlock_shared() {} - void switch_to_unique() {} + bool switch_to_unique() { return false; } }; // ---------------------------------------------------- @@ -4711,7 +4711,7 @@ public: mutex_type *mutex() const noexcept { return m_; } - void switch_to_unique() {} + bool switch_to_unique() { return false; } private: mutex_type *m_; @@ -4791,7 +4791,7 @@ public: mutex_type *mutex() const noexcept { return m_; } - void switch_to_unique() {} + bool switch_to_unique() { return false; } private: mutex_type *m_; @@ -4873,10 +4873,11 @@ public: mutex_type *mutex() const noexcept { return m_; } - void switch_to_unique() { + bool switch_to_unique() { assert(locked_shared_); unlock_shared(); lock(); + return true; }