Take care of the case where another thread inserts the same key between unlock()/lock()

This commit is contained in:
greg7mdp
2023-11-13 09:48:49 -05:00
parent 21f14d7a8e
commit ff7bd78206
2 changed files with 17 additions and 7 deletions
+12 -3
View File
@@ -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);
}
+5 -4
View File
@@ -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;
}