summaryrefslogtreecommitdiffstats
path: root/searchcore
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@online.no>2022-03-03 15:02:46 +0100
committerTor Egge <Tor.Egge@online.no>2022-03-03 15:07:04 +0100
commit74980a1e95446c78953911ce0b8029d79d0add90 (patch)
tree6cba4da7f127443ea40351ec82abe15c405412ef /searchcore
parent1fe86aad800d7c29db9bd27ed58dabdfd1c7e159 (diff)
Remove thread sanitizer lock order reversal warning for attribute context.
Diffstat (limited to 'searchcore')
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.cpp34
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.h6
2 files changed, 25 insertions, 15 deletions
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.cpp b/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.cpp
index 0069a61b818..7a86a4c5f31 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.cpp
+++ b/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.cpp
@@ -9,22 +9,34 @@
using search::attribute::IAttributeVector;
using search::attribute::ImportedAttributeVector;
-using LockGuard = std::lock_guard<std::mutex>;
namespace proton {
const IAttributeVector *
ImportedAttributesContext::getOrCacheAttribute(const vespalib::string &name, AttributeCache &attributes,
- bool stableEnumGuard, const LockGuard &) const
+ bool stableEnumGuard) const
{
+ std::unique_lock guard(_cacheMutex);
+ std::shared_future<std::unique_ptr<AttributeReadGuard>> future_read_guard;
auto itr = attributes.find(name);
if (itr != attributes.end()) {
- return itr->second->attribute();
+ future_read_guard = itr->second;
+ guard.unlock();
+ } else {
+ std::promise<std::unique_ptr<AttributeReadGuard>> promise;
+ future_read_guard = promise.get_future().share();
+ attributes.emplace(name, future_read_guard);
+ guard.unlock();
+ ImportedAttributeVector::SP result = _repo.get(name);
+ if (result) {
+ promise.set_value(result->makeReadGuard(stableEnumGuard));
+ } else {
+ promise.set_value(std::unique_ptr<AttributeReadGuard>());
+ }
}
- ImportedAttributeVector::SP result = _repo.get(name);
- if (result) {
- auto insRes = attributes.emplace(name, result->makeReadGuard(stableEnumGuard));
- return insRes.first->second->attribute();
+ auto& read_guard = future_read_guard.get();
+ if (read_guard) {
+ return read_guard->attribute();
} else {
return nullptr;
}
@@ -43,15 +55,13 @@ ImportedAttributesContext::~ImportedAttributesContext() = default;
const IAttributeVector *
ImportedAttributesContext::getAttribute(const vespalib::string &name) const
{
- LockGuard guard(_cacheMutex);
- return getOrCacheAttribute(name, _guardedAttributes, false, guard);
+ return getOrCacheAttribute(name, _guardedAttributes, false);
}
const IAttributeVector *
ImportedAttributesContext::getAttributeStableEnum(const vespalib::string &name) const
{
- LockGuard guard(_cacheMutex);
- return getOrCacheAttribute(name, _enumGuardedAttributes, true, guard);
+ return getOrCacheAttribute(name, _enumGuardedAttributes, true);
}
void
@@ -67,7 +77,7 @@ ImportedAttributesContext::getAttributeList(std::vector<const IAttributeVector *
void
ImportedAttributesContext::releaseEnumGuards()
{
- LockGuard guard(_cacheMutex);
+ std::lock_guard guard(_cacheMutex);
_enumGuardedAttributes.clear();
}
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.h b/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.h
index 4b7058fdb83..33d6cef98ff 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.h
+++ b/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.h
@@ -4,6 +4,7 @@
#include <vespa/searchcommon/attribute/iattributecontext.h>
#include <vespa/vespalib/stllike/hash_fun.h>
#include <vespa/vespalib/stllike/hash_map.h>
+#include <future>
#include <mutex>
#include <unordered_map>
@@ -31,8 +32,7 @@ private:
using ImportedAttributeVector = search::attribute::ImportedAttributeVector;
using IAttributeFunctor = search::attribute::IAttributeFunctor;
- using AttributeCache = std::unordered_map<vespalib::string, std::unique_ptr<AttributeReadGuard>, vespalib::hash<vespalib::string>>;
- using LockGuard = std::lock_guard<std::mutex>;
+ using AttributeCache = std::unordered_map<vespalib::string, std::shared_future<std::unique_ptr<AttributeReadGuard>>, vespalib::hash<vespalib::string>>;
const ImportedAttributesRepo &_repo;
mutable AttributeCache _guardedAttributes;
@@ -40,7 +40,7 @@ private:
mutable std::mutex _cacheMutex;
const IAttributeVector *getOrCacheAttribute(const vespalib::string &name, AttributeCache &attributes,
- bool stableEnumGuard, const LockGuard &) const;
+ bool stableEnumGuard) const;
public:
ImportedAttributesContext(const ImportedAttributesRepo &repo);