Skip to content

Commit 6572c9b

Browse files
committedDec 13, 2022
Add QGIS_PROTECT_QOBJECT_THREAD_ACCESS macro
Either shows a warning when a qobject function is accessed from a thread which the object doesn't have affinity with, OR causes a fatal error if the AGGRESSIVE_SAFE_MODE cmake flag is set. We should ensure this macro is present for all qobject methods which may potentially be called from threads
1 parent 6a54c9a commit 6572c9b

File tree

4 files changed

+448
-5
lines changed

4 files changed

+448
-5
lines changed
 

‎CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,8 @@ else()
692692
set(QGISDEBUG FALSE)
693693
endif()
694694

695+
set (AGGRESSIVE_SAFE_MODE FALSE CACHE BOOL "Forces a aggressive safe mode where issues like unsafe thread access will resort in fatal exceptions")
696+
695697
if(MSVC)
696698
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8 /std:c++17")
697699
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /utf-8 /std:c++17")

‎cmake_templates/qgsconfig.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@
9090

9191
#cmakedefine QGISDEBUG
9292

93+
#cmakedefine AGGRESSIVE_SAFE_MODE
94+
9395
#cmakedefine HAVE_QUICK
9496

9597
#cmakedefine HAVE_QT5SERIALPORT

‎src/core/qgsthreadingutils.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,23 @@
1919
#define SIP_NO_FILE
2020

2121
#include "qgis_core.h"
22+
#include "qgsconfig.h"
2223

2324
#include "qgsfeedback.h"
2425

2526
#include <QThread>
2627
#include <QSemaphore>
2728
#include <memory>
2829

30+
#ifdef AGGRESSIVE_SAFE_MODE
31+
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS if ( QThread::currentThread() != thread() ) {qFatal( "%s", QStringLiteral("%2 (%1:%3) is run from a different thread than the object %4 lives in [0x%5 vs 0x%6]" ).arg( QString( __FILE__ ), QString( __FUNCTION__ ), QString::number( __LINE__ ), objectName() ).arg( reinterpret_cast< qint64 >( QThread::currentThread() ), 0, 16 ).arg( reinterpret_cast< qint64 >( thread() ), 0, 16 ).toLocal8Bit().constData() ); }
32+
#elif defined(QGISDEBUG)
33+
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS if ( QThread::currentThread() != thread() ) {qWarning() << QStringLiteral("%2 (%1:%3) is run from a different thread than the object %4 lives in [0x%5 vs 0x%6]" ).arg( QString( __FILE__ ), QString( __FUNCTION__ ), QString::number( __LINE__ ), objectName() ).arg( reinterpret_cast< qint64 >( QThread::currentThread() ), 0, 16 ).arg( reinterpret_cast< qint64 >( thread() ), 0, 16 ).toLocal8Bit().constData(); }
34+
#else
35+
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS do {} while(false);
36+
#endif
37+
38+
2939
/**
3040
* \ingroup core
3141
* \brief Provides threading utilities for QGIS.

‎src/core/vector/qgsvectorlayer.cpp

Lines changed: 434 additions & 5 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.