[core] Fix potential race condition crash in symbol querying..

First half of fix for issue #11538.

Testing `if (pendingData)` didn't work if there _was_ a data update, but the update was "the data for this tile is now null". In that case, the tile's FeatureIndex would be updated, but the tile's data member would remain unchanged.

In the case of a tile's data being deleted, the matching FeatureIndex would have an empty set of bucketLayerIDs, but the _old_ data would still be in place for querying, and the symbolBuckets might not be updated yet (pending onPlacement). In this case `bucketLayerIDs.at(indexedFeature.bucketName)` could throw an out-of-range exception.
This commit is contained in:
Chris Loer
2018-03-28 14:11:55 -07:00
committed by Chris Loer
parent 2aaa038ef1
commit f9b6d5f09c
2 changed files with 8 additions and 6 deletions

View File

@@ -130,8 +130,8 @@ void GeometryTile::onLayout(LayoutResult result, const uint64_t resultCorrelatio
// replacing a tile at a different zoom that _did_ have symbols.
(void)resultCorrelationID;
nonSymbolBuckets = std::move(result.nonSymbolBuckets);
pendingFeatureIndex = std::move(result.featureIndex);
pendingData = std::move(result.tileData);
pendingFeatureIndex = { std::move(result.featureIndex) };
pendingData = { std::move(result.tileData) };
observer->onTileChanged(*this);
}
@@ -215,10 +215,12 @@ Bucket* GeometryTile::getBucket(const Layer::Impl& layer) const {
void GeometryTile::commitFeatureIndex() {
if (pendingFeatureIndex) {
featureIndex = std::move(pendingFeatureIndex);
featureIndex = std::move(*pendingFeatureIndex);
pendingFeatureIndex = nullopt;
}
if (pendingData) {
data = std::move(pendingData);
data = std::move(*pendingData);
pendingData = nullopt;
}
}

View File

@@ -125,9 +125,9 @@ private:
std::unordered_map<std::string, std::shared_ptr<Bucket>> nonSymbolBuckets;
std::unique_ptr<FeatureIndex> featureIndex;
std::unique_ptr<FeatureIndex> pendingFeatureIndex;
optional<std::unique_ptr<FeatureIndex>> pendingFeatureIndex;
std::unique_ptr<const GeometryTileData> data;
std::unique_ptr<const GeometryTileData> pendingData;
optional<std::unique_ptr<const GeometryTileData>> pendingData;
optional<AlphaImage> glyphAtlasImage;
optional<PremultipliedImage> iconAtlasImage;