Skip to content

Commit 1730a40

Browse files
committedDec 17, 2018
RAII for QgsCoordinateTransform locking
I experienced a freeze where the main thread was stuck in QgsCoordinateTransformPrivate::freeProj(), waiting for a write lock. None of the other threads had anything useful in their stack trace that would have explained why the lock was not available. The only explanation I can come up with is that an exception or thread termination was messing with the lock, leaving it in a locked state. By using RAII we can avoid this scenario.
1 parent bebc34b commit 1730a40

File tree

1 file changed

+4
-7
lines changed

1 file changed

+4
-7
lines changed
 

‎src/core/qgscoordinatetransform_p.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "qgscoordinatetransform_p.h"
1919
#include "qgslogger.h"
2020
#include "qgsapplication.h"
21+
#include "qgsreadwritelocker.h"
2122

2223
extern "C"
2324
{
@@ -225,7 +226,7 @@ void QgsCoordinateTransformPrivate::calculateTransforms( const QgsCoordinateTran
225226

226227
QPair<projPJ, projPJ> QgsCoordinateTransformPrivate::threadLocalProjData()
227228
{
228-
mProjLock.lockForRead();
229+
QgsReadWriteLocker locker( mProjLock, QgsReadWriteLocker::Read );
229230

230231
#ifdef USE_THREAD_LOCAL
231232
QMap < uintptr_t, QPair< projPJ, projPJ > >::const_iterator it = mProjProjections.constFind( reinterpret_cast< uintptr_t>( mProjContext.get() ) );
@@ -246,13 +247,11 @@ QPair<projPJ, projPJ> QgsCoordinateTransformPrivate::threadLocalProjData()
246247
if ( it != mProjProjections.constEnd() )
247248
{
248249
QPair<projPJ, projPJ> res = it.value();
249-
mProjLock.unlock();
250250
return res;
251251
}
252252

253253
// proj projections don't exist yet, so we need to create
254-
mProjLock.unlock();
255-
mProjLock.lockForWrite();
254+
locker.changeMode( QgsReadWriteLocker::Write );
256255

257256
#ifdef USE_THREAD_LOCAL
258257
QPair<projPJ, projPJ> res = qMakePair( pj_init_plus_ctx( mProjContext.get(), mSourceProjString.toUtf8() ),
@@ -263,7 +262,6 @@ QPair<projPJ, projPJ> QgsCoordinateTransformPrivate::threadLocalProjData()
263262
pj_init_plus_ctx( pContext, mDestProjString.toUtf8() ) );
264263
mProjProjections.insert( reinterpret_cast< uintptr_t>( pContext ), res );
265264
#endif
266-
mProjLock.unlock();
267265
return res;
268266
}
269267

@@ -332,15 +330,14 @@ void QgsCoordinateTransformPrivate::setFinder()
332330

333331
void QgsCoordinateTransformPrivate::freeProj()
334332
{
335-
mProjLock.lockForWrite();
333+
QgsReadWriteLocker locker( mProjLock, QgsReadWriteLocker::Write );
336334
QMap < uintptr_t, QPair< projPJ, projPJ > >::const_iterator it = mProjProjections.constBegin();
337335
for ( ; it != mProjProjections.constEnd(); ++it )
338336
{
339337
pj_free( it.value().first );
340338
pj_free( it.value().second );
341339
}
342340
mProjProjections.clear();
343-
mProjLock.unlock();
344341
}
345342

346343
///@endcond

0 commit comments

Comments
 (0)
Please sign in to comment.