From 3cfed69f99cbb0c9a542cd0d68c745ced4f06a9e Mon Sep 17 00:00:00 2001 From: Daniel Baston Date: Wed, 15 Feb 2023 21:12:56 -0500 Subject: [PATCH] PreparedLineString: Use thread-safe lazy init --- include/geos/geom/prep/PreparedLineString.h | 7 +++++-- src/geom/prep/PreparedLineString.cpp | 20 +++++++++++--------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/include/geos/geom/prep/PreparedLineString.h b/include/geos/geom/prep/PreparedLineString.h index 017e06e72f..3a9d2c4279 100644 --- a/include/geos/geom/prep/PreparedLineString.h +++ b/include/geos/geom/prep/PreparedLineString.h @@ -40,10 +40,13 @@ namespace prep { // geos::geom::prep */ class PreparedLineString : public BasicPreparedGeometry { private: - std::unique_ptr segIntFinder; + mutable std::unique_ptr segIntFinder; mutable noding::SegmentString::ConstVect segStrings; mutable std::unique_ptr indexedDistance; + mutable std::once_flag segIntFinderFlag; + mutable std::once_flag indexedDistanceFlag; + protected: public: PreparedLineString(const Geometry* geom) @@ -54,7 +57,7 @@ class PreparedLineString : public BasicPreparedGeometry { ~PreparedLineString() override; - noding::FastSegmentSetIntersectionFinder* getIntersectionFinder(); + noding::FastSegmentSetIntersectionFinder* getIntersectionFinder() const; bool intersects(const geom::Geometry* g) const override; std::unique_ptr nearestPoints(const geom::Geometry* g) const override; diff --git a/src/geom/prep/PreparedLineString.cpp b/src/geom/prep/PreparedLineString.cpp index 819a42d6cb..2da0586137 100644 --- a/src/geom/prep/PreparedLineString.cpp +++ b/src/geom/prep/PreparedLineString.cpp @@ -27,6 +27,8 @@ #include #include +#include + namespace geos { namespace geom { // geos.geom namespace prep { // geos.geom.prep @@ -44,12 +46,12 @@ PreparedLineString::~PreparedLineString() } noding::FastSegmentSetIntersectionFinder* -PreparedLineString::getIntersectionFinder() +PreparedLineString::getIntersectionFinder() const { - if(! segIntFinder) { + std::call_once(segIntFinderFlag, [this]() { noding::SegmentStringUtil::extractSegmentStrings(&getGeometry(), segStrings); - segIntFinder.reset(new noding::FastSegmentSetIntersectionFinder(&segStrings)); - } + segIntFinder = detail::make_unique(&segStrings); + }); return segIntFinder.get(); } @@ -68,12 +70,12 @@ PreparedLineString::intersects(const geom::Geometry* g) const /* public */ operation::distance::IndexedFacetDistance* -PreparedLineString:: -getIndexedFacetDistance() const +PreparedLineString::getIndexedFacetDistance() const { - if(! indexedDistance ) { - indexedDistance.reset(new operation::distance::IndexedFacetDistance(&getGeometry())); - } + std::call_once(indexedDistanceFlag, [this]() { + indexedDistance = detail::make_unique(&getGeometry()); + }); + return indexedDistance.get(); }