Skip to content

Commit

Permalink
Merge pull request #5541 from nyalldawson/thread_local
Browse files Browse the repository at this point in the history
Don't use thread_local on mingw or OpenBSD builds
  • Loading branch information
nyalldawson committed Nov 7, 2017
2 parents cc59ee4 + 5ebd398 commit e3f3499
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 2 deletions.
20 changes: 19 additions & 1 deletion CMakeLists.txt
Expand Up @@ -142,6 +142,24 @@ IF(WITH_CORE)
ENDIF (OSGEARTHQT_LIBRARY) ENDIF (OSGEARTHQT_LIBRARY)
ENDIF (WITH_GLOBE) ENDIF (WITH_GLOBE)


SET (WITH_THREAD_LOCAL TRUE CACHE BOOL "Determines whether std::thread_local should be used")
MARK_AS_ADVANCED(WITH_THREAD_LOCAL)

IF (MINGW OR CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
# MingW has broken support for thread_local, so force disabling it
# see
# https://sourceforge.net/p/mingw-w64/bugs/445/
# https://sourceforge.net/p/mingw-w64/bugs/527/
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80816

# also OpenBSD has no thread_local support, see https://issues.qgis.org/issues/17351

ELSE (MINGW OR CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
IF (WITH_THREAD_LOCAL)
SET (USE_THREAD_LOCAL TRUE) # used in qgsconfig.h
ENDIF (WITH_THREAD_LOCAL)
ENDIF (MINGW OR CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")

# Compile flag. Make it possible to turn it off. # Compile flag. Make it possible to turn it off.
SET (PEDANTIC TRUE CACHE BOOL "Determines if we should compile in pedantic mode.") SET (PEDANTIC TRUE CACHE BOOL "Determines if we should compile in pedantic mode.")


Expand Down Expand Up @@ -736,7 +754,7 @@ ENDIF (WITH_CORE)
#################################################### ####################################################
# clang-tidy # clang-tidy
SET (WITH_CLANG_TIDY FALSE CACHE BOOL "Use Clang tidy") SET (WITH_CLANG_TIDY FALSE CACHE BOOL "Use Clang tidy")
MARK_AS_ADVANCED(WITH_CORE) MARK_AS_ADVANCED(WITH_CLANG_TIDY)
IF (WITH_CORE) IF (WITH_CORE)
IF(WITH_CLANG_TIDY) IF(WITH_CLANG_TIDY)
FIND_PROGRAM( FIND_PROGRAM(
Expand Down
2 changes: 2 additions & 0 deletions cmake_templates/qgsconfig.h.in
Expand Up @@ -60,5 +60,7 @@


#cmakedefine HAVE_3D #cmakedefine HAVE_3D


#cmakedefine USE_THREAD_LOCAL

#endif #endif


27 changes: 26 additions & 1 deletion src/core/qgscoordinatetransform_p.cpp
Expand Up @@ -29,7 +29,11 @@ extern "C"


/// @cond PRIVATE /// @cond PRIVATE


#ifdef USE_THREAD_LOCAL
thread_local QgsProjContextStore QgsCoordinateTransformPrivate::mProjContext; thread_local QgsProjContextStore QgsCoordinateTransformPrivate::mProjContext;
#else
QThreadStorage< QgsProjContextStore * > QgsCoordinateTransformPrivate::mProjContext;
#endif


QgsProjContextStore::QgsProjContextStore() QgsProjContextStore::QgsProjContextStore()
{ {
Expand Down Expand Up @@ -185,7 +189,22 @@ QPair<projPJ, projPJ> QgsCoordinateTransformPrivate::threadLocalProjData()
{ {
mProjLock.lockForRead(); mProjLock.lockForRead();


#ifdef USE_THREAD_LOCAL
QMap < uintptr_t, QPair< projPJ, projPJ > >::const_iterator it = mProjProjections.constFind( reinterpret_cast< uintptr_t>( mProjContext.get() ) ); QMap < uintptr_t, QPair< projPJ, projPJ > >::const_iterator it = mProjProjections.constFind( reinterpret_cast< uintptr_t>( mProjContext.get() ) );
#else
projCtx pContext = nullptr;
if ( mProjContext.hasLocalData() )
{
pContext = mProjContext.localData()->get();
}
else
{
mProjContext.setLocalData( new QgsProjContextStore() );
pContext = mProjContext.localData()->get();
}
QMap < uintptr_t, QPair< projPJ, projPJ > >::const_iterator it = mProjProjections.constFind( reinterpret_cast< uintptr_t>( pContext ) );
#endif

if ( it != mProjProjections.constEnd() ) if ( it != mProjProjections.constEnd() )
{ {
QPair<projPJ, projPJ> res = it.value(); QPair<projPJ, projPJ> res = it.value();
Expand All @@ -196,9 +215,16 @@ QPair<projPJ, projPJ> QgsCoordinateTransformPrivate::threadLocalProjData()
// proj projections don't exist yet, so we need to create // proj projections don't exist yet, so we need to create
mProjLock.unlock(); mProjLock.unlock();
mProjLock.lockForWrite(); mProjLock.lockForWrite();

#ifdef USE_THREAD_LOCAL
QPair<projPJ, projPJ> res = qMakePair( pj_init_plus_ctx( mProjContext.get(), mSourceProjString.toUtf8() ), QPair<projPJ, projPJ> res = qMakePair( pj_init_plus_ctx( mProjContext.get(), mSourceProjString.toUtf8() ),
pj_init_plus_ctx( mProjContext.get(), mDestProjString.toUtf8() ) ); pj_init_plus_ctx( mProjContext.get(), mDestProjString.toUtf8() ) );
mProjProjections.insert( reinterpret_cast< uintptr_t>( mProjContext.get() ), res ); mProjProjections.insert( reinterpret_cast< uintptr_t>( mProjContext.get() ), res );
#else
QPair<projPJ, projPJ> res = qMakePair( pj_init_plus_ctx( pContext, mSourceProjString.toUtf8() ),
pj_init_plus_ctx( pContext, mDestProjString.toUtf8() ) );
mProjProjections.insert( reinterpret_cast< uintptr_t>( pContext ), res );
#endif
mProjLock.unlock(); mProjLock.unlock();
return res; return res;
} }
Expand Down Expand Up @@ -335,4 +361,3 @@ void QgsCoordinateTransformPrivate::freeProj()
} }


///@endcond ///@endcond

10 changes: 10 additions & 0 deletions src/core/qgscoordinatetransform_p.h
Expand Up @@ -18,6 +18,7 @@
#define QGSCOORDINATETRANSFORMPRIVATE_H #define QGSCOORDINATETRANSFORMPRIVATE_H


#define SIP_NO_FILE #define SIP_NO_FILE
#include "qgsconfig.h"


/// @cond PRIVATE /// @cond PRIVATE


Expand All @@ -31,6 +32,11 @@
// //


#include <QSharedData> #include <QSharedData>

#ifndef USE_THREAD_LOCAL
#include <QThreadStorage>
#endif

#include "qgscoordinatereferencesystem.h" #include "qgscoordinatereferencesystem.h"


typedef void *projPJ; typedef void *projPJ;
Expand Down Expand Up @@ -100,7 +106,11 @@ class QgsCoordinateTransformPrivate : public QSharedData
* Thread local proj context storage. A new proj context will be created * Thread local proj context storage. A new proj context will be created
* for every thread. * for every thread.
*/ */
#ifdef USE_THREAD_LOCAL
static thread_local QgsProjContextStore mProjContext; static thread_local QgsProjContextStore mProjContext;
#else
static QThreadStorage< QgsProjContextStore * > mProjContext;
#endif


QReadWriteLock mProjLock; QReadWriteLock mProjLock;
QMap < uintptr_t, QPair< projPJ, projPJ > > mProjProjections; QMap < uintptr_t, QPair< projPJ, projPJ > > mProjProjections;
Expand Down

0 comments on commit e3f3499

Please sign in to comment.