From 4e770dc8156d0fdce5c9c6e0c71935fe4d18648e Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Thu, 2 May 2013 17:02:54 -0500 Subject: Add ability to control cross thread signal slot handling method --- src/kernel/qobject.cpp | 36 ++++++++++++++++++++++++++++++------ src/kernel/qobject.h | 1 + 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/kernel/qobject.cpp b/src/kernel/qobject.cpp index 20973c5..a3f4f18 100644 --- a/src/kernel/qobject.cpp +++ b/src/kernel/qobject.cpp @@ -66,9 +66,14 @@ class QObjectPrivate { { public: #ifndef QT_NO_USERDATA - QObjectPrivate( uint s ) : QPtrVector(s){ setAutoDelete( TRUE ); } + QObjectPrivate( uint s ) : QPtrVector(s) { + ownThread = NULL; + disableThreadPostedEvents = false; + setAutoDelete( TRUE ); + } #endif QThread* ownThread; + bool disableThreadPostedEvents; }; #if defined(QT_THREAD_SUPPORT) @@ -151,6 +156,25 @@ void QObject::moveToThread(QThread *targetThread) setThreadObject_helper(targetThread); } +/*! + Changes the way cross thread signals are handled + If disable is FALSE, signals emitted from one thread will be + posted to any other connected threads' event loops (default). + + If disable is TRUE, calls to emit from one thread + will immediately execute slots in another thread. + This mode of operation is inherently unsafe and is provided + solely to support thread management by a third party application. + */ +void QObject::disableThreadPostedEvents(bool disable) { + if ( !d ) { + d = new QObjectPrivate(0); + } + + d->ownThread = QThread::currentThreadObject(); + d->disableThreadPostedEvents = disable; +} + #endif class QSenderObjectList : public QObjectList, public QShared @@ -957,7 +981,7 @@ bool QObject::event( QEvent *e ) { QMetaCallEvent* metaEvent = dynamic_cast(e); if (metaEvent) { - if (d->ownThread == QThread::currentThreadObject()) { + if ((d->disableThreadPostedEvents) || (d->ownThread == QThread::currentThreadObject())) { QSenderObjectList* sol; QObject* oldSender = 0; sol = senderObjects; @@ -2592,7 +2616,7 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o ) sol->currentSender = this; } if ( c->memberType() == QSIGNAL_CODE ) { - if (object->d->ownThread == currentThread) { + if ((d->disableThreadPostedEvents) || (object->d->ownThread == currentThread)) { object->qt_emit( c->member(), o ); } else { @@ -2602,7 +2626,7 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o ) } } else { - if (object->d->ownThread == currentThread) { + if ((d->disableThreadPostedEvents) || (object->d->ownThread == currentThread)) { object->qt_invoke( c->member(), o ); } else { @@ -2632,7 +2656,7 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o ) sol->currentSender = this; } if ( c->memberType() == QSIGNAL_CODE ) { - if (object->d->ownThread == currentThread) { + if ((d->disableThreadPostedEvents) || (object->d->ownThread == currentThread)) { object->qt_emit( c->member(), o ); } else { @@ -2642,7 +2666,7 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o ) } } else { - if (object->d->ownThread == currentThread) { + if ((d->disableThreadPostedEvents) || (object->d->ownThread == currentThread)) { object->qt_invoke( c->member(), o ); } else { diff --git a/src/kernel/qobject.h b/src/kernel/qobject.h index 2f469ba..89cbfe2 100644 --- a/src/kernel/qobject.h +++ b/src/kernel/qobject.h @@ -226,6 +226,7 @@ public: #ifdef QT_THREAD_SUPPORT QThread* contextThreadObject() const; void moveToThread(QThread *targetThread); + void disableThreadPostedEvents(bool disable); #endif private: -- cgit v1.2.3