diff options
author | Tor Egge <Tor.Egge@online.no> | 2022-03-03 15:02:46 +0100 |
---|---|---|
committer | Tor Egge <Tor.Egge@online.no> | 2022-03-03 15:07:04 +0100 |
commit | 74980a1e95446c78953911ce0b8029d79d0add90 (patch) | |
tree | 6cba4da7f127443ea40351ec82abe15c405412ef /searchcore | |
parent | 1fe86aad800d7c29db9bd27ed58dabdfd1c7e159 (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.cpp | 34 | ||||
-rw-r--r-- | searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.h | 6 |
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); |