Skip to content
Permalink
Browse files

Don't use thread_local on mingw or OpenBSD builds

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

So on these platforms we fall back to using QThreadStorage.

Fixes #17351
  • Loading branch information
nyalldawson committed Nov 5, 2017
1 parent d269f34 commit 265be41d7c1cb0bb9d39aac3285c2c8fb40ffa47
Showing with 57 additions and 2 deletions.
  1. +19 −1 CMakeLists.txt
  2. +2 −0 cmake_templates/qgsconfig.h.in
  3. +26 −1 src/core/qgscoordinatetransform_p.cpp
  4. +10 −0 src/core/qgscoordinatetransform_p.h
@@ -142,6 +142,24 @@ IF(WITH_CORE)
ENDIF (OSGEARTHQT_LIBRARY)
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 "FreeBSD" 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 "FreeBSD" 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 "FreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")

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

@@ -736,7 +754,7 @@ ENDIF (WITH_CORE)
####################################################
# 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_CLANG_TIDY)
FIND_PROGRAM(
@@ -60,5 +60,7 @@

#cmakedefine HAVE_3D

#cmakedefine USE_THREAD_LOCAL

#endif

@@ -29,7 +29,11 @@ extern "C"

/// @cond PRIVATE

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

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

#ifdef USE_THREAD_LOCAL
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() )
{
QPair<projPJ, projPJ> res = it.value();
@@ -196,9 +215,16 @@ QPair<projPJ, projPJ> QgsCoordinateTransformPrivate::threadLocalProjData()
// proj projections don't exist yet, so we need to create
mProjLock.unlock();
mProjLock.lockForWrite();

#ifdef USE_THREAD_LOCAL
QPair<projPJ, projPJ> res = qMakePair( pj_init_plus_ctx( mProjContext.get(), mSourceProjString.toUtf8() ),
pj_init_plus_ctx( mProjContext.get(), mDestProjString.toUtf8() ) );
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();
return res;
}
@@ -335,4 +361,3 @@ void QgsCoordinateTransformPrivate::freeProj()
}

///@endcond

@@ -18,6 +18,7 @@
#define QGSCOORDINATETRANSFORMPRIVATE_H

#define SIP_NO_FILE
#include "qgsconfig.h"

/// @cond PRIVATE

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

#include <QSharedData>

#ifndef USE_THREAD_LOCAL
#include <QThreadStorage>
#endif

#include "qgscoordinatereferencesystem.h"

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

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

0 comments on commit 265be41

Please sign in to comment.
You can’t perform that action at this time.