Skip to content

Commit

Permalink
Ensure master PJ object is always cleaned up when the context is dest…
Browse files Browse the repository at this point in the history
…royed too
  • Loading branch information
nyalldawson committed Jan 22, 2020
1 parent e60d0ac commit b418567
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
8 changes: 4 additions & 4 deletions src/core/qgscoordinatereferencesystem.cpp
Expand Up @@ -665,7 +665,7 @@ bool QgsCoordinateReferenceSystem::loadFromDatabase( const QString &db, const QS

{
QgsProjUtils::proj_pj_unique_ptr crs( proj_create_from_database( QgsProjContext::get(), auth.toLatin1(), code.toLatin1(), PJ_CATEGORY_CRS, false, nullptr ) );
d->mPj = QgsProjUtils::crsToSingleCrs( crs.get() );
d->setPj( QgsProjUtils::crsToSingleCrs( crs.get() ) );
}

d->mIsValid = static_cast< bool >( d->mPj );
Expand Down Expand Up @@ -1498,7 +1498,7 @@ void QgsCoordinateReferenceSystem::setProjString( const QString &proj4String )
PJ_CONTEXT *ctx = QgsProjContext::get();

{
d->mPj.reset( proj_create( ctx, trimmed.toLatin1().constData() ) );
d->setPj( QgsProjUtils::proj_pj_unique_ptr( proj_create( ctx, trimmed.toLatin1().constData() ) ) );
}

if ( !d->mPj )
Expand Down Expand Up @@ -1552,7 +1552,7 @@ bool QgsCoordinateReferenceSystem::setWktString( const QString &wkt, bool allowP
PROJ_STRING_LIST warnings = nullptr;
PROJ_STRING_LIST grammerErrors = nullptr;
{
d->mPj.reset( proj_create_from_wkt( QgsProjContext::get(), wkt.toLatin1().constData(), nullptr, &warnings, &grammerErrors ) );
d->setPj( QgsProjUtils::proj_pj_unique_ptr( proj_create_from_wkt( QgsProjContext::get(), wkt.toLatin1().constData(), nullptr, &warnings, &grammerErrors ) ) );
}

res = static_cast< bool >( d->mPj );
Expand Down Expand Up @@ -2456,7 +2456,7 @@ bool QgsCoordinateReferenceSystem::loadFromAuthCode( const QString &auth, const
getOperationAndEllipsoidFromProjString( proj4, operation, ellipsoid );
d->mProjectionAcronym = operation;
d->mEllipsoidAcronym.clear();
d->mPj = std::move( crs );
d->setPj( std::move( crs ) );

const QString dbVals = sAuthIdToQgisSrsIdMap.value( QStringLiteral( "%1:%2" ).arg( auth, code ).toUpper() );
QString srsId;
Expand Down
22 changes: 22 additions & 0 deletions src/core/qgscoordinatereferencesystem_p.h
Expand Up @@ -153,6 +153,22 @@ class QgsCoordinateReferenceSystemPrivate : public QSharedData
// this is the "master" proj object, to be used as a template for new proj objects created on different threads ONLY.
// Always use threadLocalProjObject() instead of this.
QgsProjUtils::proj_pj_unique_ptr mPj;
PJ_CONTEXT *mPjParentContext = nullptr;

void setPj( QgsProjUtils::proj_pj_unique_ptr obj )
{
if ( mPj )
{
PJ_CONTEXT *tmpContext = proj_context_create();
proj_assign_context( mPj.get(), tmpContext );
mPj.reset();
proj_context_destroy( tmpContext );
}

mPj = std::move( obj );
mPjParentContext = QgsProjContext::get();
}

#else
OGRSpatialReferenceH mCRS;
#endif
Expand Down Expand Up @@ -204,6 +220,12 @@ class QgsCoordinateReferenceSystemPrivate : public QSharedData
mProjObjects.erase( it );
}

if ( mPjParentContext == pj_context )
{
mPj.reset();
mPjParentContext = nullptr;
}

return mProjObjects.isEmpty();
}
#endif
Expand Down

0 comments on commit b418567

Please sign in to comment.