Skip to content

Commit

Permalink
Add QGIS_PROTECT_QOBJECT_THREAD_ACCESS macro
Browse files Browse the repository at this point in the history
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
  • Loading branch information
nyalldawson committed Dec 13, 2022
1 parent 6a54c9a commit 6572c9b
Show file tree
Hide file tree
Showing 4 changed files with 448 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Expand Up @@ -692,6 +692,8 @@ else()
set(QGISDEBUG FALSE)
endif()

set (AGGRESSIVE_SAFE_MODE FALSE CACHE BOOL "Forces a aggressive safe mode where issues like unsafe thread access will resort in fatal exceptions")

if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8 /std:c++17")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /utf-8 /std:c++17")
Expand Down
2 changes: 2 additions & 0 deletions cmake_templates/qgsconfig.h.in
Expand Up @@ -90,6 +90,8 @@

#cmakedefine QGISDEBUG

#cmakedefine AGGRESSIVE_SAFE_MODE

#cmakedefine HAVE_QUICK

#cmakedefine HAVE_QT5SERIALPORT
Expand Down
10 changes: 10 additions & 0 deletions src/core/qgsthreadingutils.h
Expand Up @@ -19,13 +19,23 @@
#define SIP_NO_FILE

#include "qgis_core.h"
#include "qgsconfig.h"

#include "qgsfeedback.h"

#include <QThread>
#include <QSemaphore>
#include <memory>

#ifdef AGGRESSIVE_SAFE_MODE
#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() ); }
#elif defined(QGISDEBUG)
#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(); }
#else
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS do {} while(false);
#endif


/**
* \ingroup core
* \brief Provides threading utilities for QGIS.
Expand Down

0 comments on commit 6572c9b

Please sign in to comment.