summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Loer <chris.loer@gmail.com>2018-03-28 14:11:55 -0700
committerChris Loer <chris.loer@gmail.com>2018-03-28 14:35:54 -0700
commit26edac0f66b2f49f059ceec22bf5fb6f66bf9ead (patch)
treebffe071158d923177868f7041b42cef25c231741
parentfbd6e2b618d40c0dee18430f207ed4514e6cb150 (diff)
downloadqtlocation-mapboxgl-26edac0f66b2f49f059ceec22bf5fb6f66bf9ead.tar.gz
[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.
-rw-r--r--src/mbgl/tile/geometry_tile.cpp10
-rw-r--r--src/mbgl/tile/geometry_tile.hpp4
2 files changed, 8 insertions, 6 deletions
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index 82d0c91806..7fb0c9922d 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -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;
}
}
diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp
index 00a4aafadf..0c6adf0337 100644
--- a/src/mbgl/tile/geometry_tile.hpp
+++ b/src/mbgl/tile/geometry_tile.hpp
@@ -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;