16#ifndef QGSTHREADINGUTILS_H
17#define QGSTHREADINGUTILS_H
27#if defined(QGISDEBUG) || defined(AGGRESSIVE_SAFE_MODE)
31#include <QCoreApplication>
34#ifdef __clang_analyzer__
35#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS do {} while(false);
36#elif defined(AGGRESSIVE_SAFE_MODE)
37#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() ); }
38#elif defined(QGISDEBUG)
39#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(); }
41#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS do {} while(false);
46#ifdef __clang_analyzer__
47#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS_NON_FATAL do {} while(false);
48#elif defined(QGISDEBUG)
49#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS_NON_FATAL 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(); }
51#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS_NON_FATAL do {} while(false);
54#ifdef __clang_analyzer__
55#define QGIS_CHECK_QOBJECT_THREAD_EQUALITY(other) do {} while(false);(void)other;
56#elif defined(AGGRESSIVE_SAFE_MODE)
57#define QGIS_CHECK_QOBJECT_THREAD_EQUALITY(other) if ( other->thread() != thread() ) {qFatal( "%s", QStringLiteral("%2 (%1:%3) Object %4 is from a different thread than the object %5 lives in [0x%6 vs 0x%7]" ).arg( QString( __FILE__ ), QString( __FUNCTION__ ), QString::number( __LINE__ ), other->objectName(), objectName() ).arg( reinterpret_cast< qint64 >( QThread::currentThread() ), 0, 16 ).arg( reinterpret_cast< qint64 >( thread() ), 0, 16 ).toLocal8Bit().constData() ); }
58#elif defined(QGISDEBUG)
59#define QGIS_CHECK_QOBJECT_THREAD_EQUALITY(other) if ( other->thread() != thread() ) {qWarning() << QStringLiteral("%2 (%1:%3) Object %4 is from a different thread than the object %5 lives in [0x%6 vs 0x%7]" ).arg( QString( __FILE__ ), QString( __FUNCTION__ ), QString::number( __LINE__ ), other->objectName(), objectName() ).arg( reinterpret_cast< qint64 >( QThread::currentThread() ), 0, 16 ).arg( reinterpret_cast< qint64 >( thread() ), 0, 16 ).toLocal8Bit().constData(); }
61#define QGIS_CHECK_QOBJECT_THREAD_EQUALITY(other) do {} while(false);(void)other;
91 template <
typename Func>
96 if ( QThread::currentThread() == qApp->thread() )
108 QSemaphore semaphoreMainThreadReady( 1 );
113 QSemaphore semaphoreWorkerThreadReady( 1 );
117 semaphoreMainThreadReady.acquire();
118 semaphoreWorkerThreadReady.acquire();
120 const std::function<void()> waitFunc = [&semaphoreMainThreadReady, &semaphoreWorkerThreadReady]()
125 semaphoreMainThreadReady.release();
128 semaphoreWorkerThreadReady.acquire();
131 QMetaObject::invokeMethod( qApp, waitFunc, Qt::QueuedConnection );
135 while ( !semaphoreMainThreadReady.tryAcquire( 1, 100 ) )
137 if ( feedback->isCanceled() )
139 semaphoreWorkerThreadReady.release();
149 semaphoreWorkerThreadReady.release();
152 QMetaObject::invokeMethod( qApp, func, Qt::BlockingQueuedConnection );
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Provides threading utilities for QGIS.
static bool runOnMainThread(const Func &func, QgsFeedback *feedback=nullptr)
Guarantees that func is executed on the main thread.