diff options
author | Tor Brede Vekterli <vekterli@yahooinc.com> | 2022-03-03 14:35:25 +0000 |
---|---|---|
committer | Tor Brede Vekterli <vekterli@yahooinc.com> | 2022-03-03 14:55:02 +0000 |
commit | f455b53f3733ca0848d04e3587fd3d70c35ebf54 (patch) | |
tree | cce7adb8a022e215b1140419cda000cc1802970e /document | |
parent | 6f78fdc9750ad3ac03b14166b6838c628487458c (diff) |
Explicitly precompute GlobalId for reference values to avoid lazy init race
This is a workaround for `DocumentId::getGlobalId()`'s lazy GID computation
currently not being thread safe in a `const` context.
The following race was previously possible:
* Attribute writer thread calls `DocumentId::getGlobalId` when applying
the reference value update to a reference attribute. Writes GID and
flag.
* Shared executor thread calls `DocumentId::operator=` with the same ID
instance as the rhs argument when applying the reference value update
to the doc store. Causes a read race with the above write.
Diffstat (limited to 'document')
-rw-r--r-- | document/src/vespa/document/base/documentid.cpp | 3 | ||||
-rw-r--r-- | document/src/vespa/document/fieldvalue/referencefieldvalue.cpp | 2 |
2 files changed, 4 insertions, 1 deletions
diff --git a/document/src/vespa/document/base/documentid.cpp b/document/src/vespa/document/base/documentid.cpp index f3045cd0758..cb5320db538 100644 --- a/document/src/vespa/document/base/documentid.cpp +++ b/document/src/vespa/document/base/documentid.cpp @@ -59,8 +59,9 @@ DocumentId::calculateGlobalId() const IdString::LocationType location(_id.getLocation()); memcpy(key, &location, 4); - _globalId.first = true; + // FIXME this lazy init mechanic does not satisfy const thread safety _globalId.second.set(key); + _globalId.first = true; } std::ostream & diff --git a/document/src/vespa/document/fieldvalue/referencefieldvalue.cpp b/document/src/vespa/document/fieldvalue/referencefieldvalue.cpp index 83890c1acfc..328e5b67151 100644 --- a/document/src/vespa/document/fieldvalue/referencefieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/referencefieldvalue.cpp @@ -75,6 +75,8 @@ void ReferenceFieldValue::setDeserializedDocumentId(const DocumentId& id) { assert(_dataType != nullptr); requireIdOfMatchingType(id, _dataType->getTargetType()); _documentId = id; + // Pre-cache GID to ensure it's not attempted lazily initialized later in a racing manner. + (void) _documentId.getGlobalId(); _altered = false; } |