Skip to content

Commit

Permalink
Make QgsCRSCache thread safe
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 5, 2016
1 parent 339d061 commit 867dbe5
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 9 deletions.
3 changes: 3 additions & 0 deletions python/core/qgscrscache.sip
Expand Up @@ -88,4 +88,7 @@ class QgsCRSCache
protected:
QgsCRSCache();

private:

QgsCRSCache( const QgsCRSCache& other );
};
58 changes: 49 additions & 9 deletions src/core/qgscrscache.cpp
Expand Up @@ -95,11 +95,15 @@ QgsCRSCache* QgsCRSCache::instance()
}

QgsCRSCache::QgsCRSCache()
: mCRSLock( QReadWriteLock::Recursive )
, mCRSProj4Lock( QReadWriteLock::Recursive )
, mCRSSrsIdLock( QReadWriteLock::Recursive )
{
}

void QgsCRSCache::updateCRSCache( const QString& authid )
{
QWriteLocker lock( &mCRSLock );
QgsCoordinateReferenceSystem s;
if ( s.createFromOgcWmsCrs( authid ) )
{
Expand All @@ -120,19 +124,31 @@ QgsCoordinateReferenceSystem QgsCRSCache::crsByAuthId( const QString& authid )

QgsCoordinateReferenceSystem QgsCRSCache::crsByOgcWmsCrs( const QString& ogcCrs ) const
{
mCRSLock.lockForRead();
QHash< QString, QgsCoordinateReferenceSystem >::const_iterator crsIt = mCRS.constFind( ogcCrs );
if ( crsIt == mCRS.constEnd() )
{
mCRSLock.unlock();
mCRSLock.lockForWrite();
QgsCoordinateReferenceSystem s;
if ( ! s.createFromOgcWmsCrs( ogcCrs ) )
{
return mCRS.insert( ogcCrs, mInvalidCRS ).value();
QgsCoordinateReferenceSystem result = mCRS.insert( ogcCrs, mInvalidCRS ).value();
mCRSLock.unlock();
return result;
}
else
{
QgsCoordinateReferenceSystem result = mCRS.insert( ogcCrs, s ).value();
mCRSLock.unlock();
return result;
}
return mCRS.insert( ogcCrs, s ).value();
}
else
{
return crsIt.value();
QgsCoordinateReferenceSystem result = crsIt.value();
mCRSLock.unlock();
return result;
}
}

Expand All @@ -143,36 +159,60 @@ QgsCoordinateReferenceSystem QgsCRSCache::crsByEpsgId( long epsg ) const

QgsCoordinateReferenceSystem QgsCRSCache::crsByProj4( const QString& proj4 ) const
{
mCRSProj4Lock.lockForRead();
QHash< QString, QgsCoordinateReferenceSystem >::const_iterator crsIt = mCRSProj4.constFind( proj4 );
if ( crsIt == mCRSProj4.constEnd() )
{
mCRSProj4Lock.unlock();
mCRSProj4Lock.lockForWrite();
QgsCoordinateReferenceSystem s;
if ( ! s.createFromProj4( proj4 ) )
{
return mCRSProj4.insert( proj4, mInvalidCRS ).value();
QgsCoordinateReferenceSystem result = mCRSProj4.insert( proj4, mInvalidCRS ).value();
mCRSProj4Lock.unlock();
return result;
}
else
{
QgsCoordinateReferenceSystem result = mCRSProj4.insert( proj4, s ).value();
mCRSProj4Lock.unlock();
return result;
}
return mCRSProj4.insert( proj4, s ).value();
}
else
{
return crsIt.value();
QgsCoordinateReferenceSystem result = crsIt.value();
mCRSProj4Lock.unlock();
return result;
}
}

QgsCoordinateReferenceSystem QgsCRSCache::crsBySrsId( long srsId ) const
{
mCRSSrsIdLock.lockForRead();
QHash< long, QgsCoordinateReferenceSystem >::const_iterator crsIt = mCRSSrsId.constFind( srsId );
if ( crsIt == mCRSSrsId.constEnd() )
{
mCRSSrsIdLock.unlock();
mCRSSrsIdLock.lockForWrite();
QgsCoordinateReferenceSystem s;
if ( ! s.createFromSrsId( srsId ) )
{
return mCRSSrsId.insert( srsId, mInvalidCRS ).value();
QgsCoordinateReferenceSystem result = mCRSSrsId.insert( srsId, mInvalidCRS ).value();
mCRSSrsIdLock.unlock();
return result;
}
else
{
QgsCoordinateReferenceSystem result = mCRSSrsId.insert( srsId, s ).value();
mCRSSrsIdLock.unlock();
return result;
}
return mCRSSrsId.insert( srsId, s ).value();
}
else
{
return crsIt.value();
QgsCoordinateReferenceSystem result = crsIt.value();
mCRSSrsIdLock.unlock();
return result;
}
}
6 changes: 6 additions & 0 deletions src/core/qgscrscache.h
Expand Up @@ -20,6 +20,7 @@

#include "qgscoordinatereferencesystem.h"
#include <QHash>
#include <QReadWriteLock>

class QgsCoordinateTransform;

Expand Down Expand Up @@ -116,12 +117,17 @@ class CORE_EXPORT QgsCRSCache

private:

mutable QReadWriteLock mCRSLock;
mutable QHash< QString, QgsCoordinateReferenceSystem > mCRS;
mutable QReadWriteLock mCRSProj4Lock;
mutable QHash< QString, QgsCoordinateReferenceSystem > mCRSProj4;
mutable QReadWriteLock mCRSSrsIdLock;
mutable QHash< long, QgsCoordinateReferenceSystem > mCRSSrsId;

/** CRS that is not initialized (returned in case of error)*/
QgsCoordinateReferenceSystem mInvalidCRS;

QgsCRSCache( const QgsCRSCache& other );
};

#endif // QGSCRSCACHE_H

0 comments on commit 867dbe5

Please sign in to comment.