summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/kernel/qeventloop_unix_glib.cpp4
-rw-r--r--src/kernel/qobject.cpp20
-rw-r--r--src/kernel/qthread.cpp23
-rw-r--r--src/kernel/qthread.h5
-rw-r--r--src/kernel/qthread_unix.cpp8
-rw-r--r--src/tools/qthreadinstance_p.h1
-rw-r--r--tutorial/t15/main.cpp10
7 files changed, 58 insertions, 13 deletions
diff --git a/src/kernel/qeventloop_unix_glib.cpp b/src/kernel/qeventloop_unix_glib.cpp
index 6924fcd..feff675 100644
--- a/src/kernel/qeventloop_unix_glib.cpp
+++ b/src/kernel/qeventloop_unix_glib.cpp
@@ -688,7 +688,7 @@ int QEventLoop::activateTimers()
QTimerEvent e( t->id );
#if defined(QT_THREAD_SUPPORT)
// Be careful...the current thread may not be the target object's thread!
- if ((!t->obj) || (t->obj && (t->obj->contextThreadObject() == QThread::currentThreadObject()))) {
+ if ((!t->obj) || (QThread::currentThreadObject()->threadPostedEventsDisabled()) || (t->obj && (t->obj->contextThreadObject() == QThread::currentThreadObject()))) {
QApplication::sendEvent( t->obj, &e ); // send event
}
else {
@@ -731,7 +731,7 @@ int QEventLoop::activateSocketNotifiers()
sn->pending = FALSE;
#if defined(QT_THREAD_SUPPORT)
// Be careful...the current thread may not be the target object's thread!
- if ((!sn->obj) || (sn->obj && (sn->obj->contextThreadObject() == QThread::currentThreadObject()))) {
+ if ((!sn->obj) || (QThread::currentThreadObject()->threadPostedEventsDisabled()) || (sn->obj && (sn->obj->contextThreadObject() == QThread::currentThreadObject()))) {
QApplication::sendEvent( sn->obj, &event ); // send event
}
else {
diff --git a/src/kernel/qobject.cpp b/src/kernel/qobject.cpp
index 9e5ac8e..247db41 100644
--- a/src/kernel/qobject.cpp
+++ b/src/kernel/qobject.cpp
@@ -2727,7 +2727,7 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
sol->currentSender = this;
}
if ( c->memberType() == QSIGNAL_CODE ) {
- if ((d->disableThreadPostedEvents) || (object->d->ownThread == currentThread)) {
+ if ((d->disableThreadPostedEvents) || (object->d->disableThreadPostedEvents) || (currentThread->threadPostedEventsDisabled()) || (object->d->ownThread == currentThread)) {
#ifdef QT_THREAD_SUPPORT
sol->listMutex->unlock();
#endif // QT_THREAD_SUPPORT
@@ -2738,12 +2738,15 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
}
else {
if (object->d->ownThread && !object->d->ownThread->finished()) {
+#ifdef QT_DEBUG
+ qDebug("QObject::activate_signal: Emitting cross-thread signal from object %p (member %d receiver %p) (1)\n\r", this, c->member(), object);
+#endif // QT_DEBUG
QApplication::postEvent(object, new QMetaCallEvent(c->member(), this, deepCopyQUObjectArray(o), QMetaCallEvent::MetaCallEmit));
}
}
}
else {
- if ((d->disableThreadPostedEvents) || (object->d->ownThread == currentThread)) {
+ if ((d->disableThreadPostedEvents) || (object->d->disableThreadPostedEvents) || (currentThread->threadPostedEventsDisabled()) || (object->d->ownThread == currentThread)) {
#ifdef QT_THREAD_SUPPORT
sol->listMutex->unlock();
#endif // QT_THREAD_SUPPORT
@@ -2754,6 +2757,9 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
}
else {
if (object->d->ownThread && !object->d->ownThread->finished()) {
+#ifdef QT_DEBUG
+ qDebug("QObject::activate_signal: Invoking cross-thread method from object %p (member %d receiver %p) (1)\n\r", this, c->member(), object);
+#endif // QT_DEBUG
QApplication::postEvent(object, new QMetaCallEvent(c->member(), this, deepCopyQUObjectArray(o), QMetaCallEvent::MetaCallInvoke));
}
}
@@ -2788,7 +2794,7 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
sol->currentSender = this;
}
if ( c->memberType() == QSIGNAL_CODE ) {
- if ((d->disableThreadPostedEvents) || (object->d->ownThread == currentThread)) {
+ if ((d->disableThreadPostedEvents) || (object->d->disableThreadPostedEvents) || (currentThread->threadPostedEventsDisabled()) || (object->d->ownThread == currentThread)) {
#ifdef QT_THREAD_SUPPORT
sol->listMutex->unlock();
#endif // QT_THREAD_SUPPORT
@@ -2799,12 +2805,15 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
}
else {
if (object->d->ownThread && !object->d->ownThread->finished()) {
+#ifdef QT_DEBUG
+ qDebug("QObject::activate_signal: Emitting cross-thread signal from object %p (member %d receiver %p) (2)\n\r", this, c->member(), object);
+#endif // QT_DEBUG
QApplication::postEvent(object, new QMetaCallEvent(c->member(), this, deepCopyQUObjectArray(o), QMetaCallEvent::MetaCallEmit));
}
}
}
else {
- if ((d->disableThreadPostedEvents) || (object->d->ownThread == currentThread)) {
+ if ((d->disableThreadPostedEvents) || (object->d->disableThreadPostedEvents) || (currentThread->threadPostedEventsDisabled()) || (object->d->ownThread == currentThread)) {
#ifdef QT_THREAD_SUPPORT
sol->listMutex->unlock();
#endif // QT_THREAD_SUPPORT
@@ -2815,6 +2824,9 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
}
else {
if (object->d->ownThread && !object->d->ownThread->finished()) {
+#ifdef QT_DEBUG
+ qDebug("QObject::activate_signal: Invoking cross-thread method from object %p (member %d receiver %p) (2)\n\r", this, c->member(), object);
+#endif // QT_DEBUG
QApplication::postEvent(object, new QMetaCallEvent(c->member(), this, deepCopyQUObjectArray(o), QMetaCallEvent::MetaCallInvoke));
}
}
diff --git a/src/kernel/qthread.cpp b/src/kernel/qthread.cpp
index 93fc3f2..4eeb823 100644
--- a/src/kernel/qthread.cpp
+++ b/src/kernel/qthread.cpp
@@ -224,6 +224,29 @@ bool QThread::running() const
}
/*!
+ Changes the way cross thread signals are handled
+ If disable is FALSE, signals emitted from this thread will be
+ posted to any other connected threads' event loops (default).
+
+ If disable is TRUE, calls to emit from this 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 QThread::setThreadPostedEventsDisabled(bool disable)
+{
+ d->disableThreadPostedEvents = disable;
+}
+
+/*!
+ Returns TRUE if thread posted events are disabled, FALSE if not
+ */
+bool QThread::threadPostedEventsDisabled() const
+{
+ return d->disableThreadPostedEvents;
+}
+
+/*!
\fn void QThread::run()
This method is pure virtual, and must be implemented in derived
diff --git a/src/kernel/qthread.h b/src/kernel/qthread.h
index 80448a0..675e3a3 100644
--- a/src/kernel/qthread.h
+++ b/src/kernel/qthread.h
@@ -113,9 +113,12 @@ public:
CleanupMergeObjects
};
- CleanupType cleanupType();
+ CleanupType cleanupType() const;
void setCleanupType(CleanupType);
+ bool threadPostedEventsDisabled() const;
+ void setThreadPostedEventsDisabled(bool);
+
protected:
virtual void run() = 0;
diff --git a/src/kernel/qthread_unix.cpp b/src/kernel/qthread_unix.cpp
index a48468b..530d401 100644
--- a/src/kernel/qthread_unix.cpp
+++ b/src/kernel/qthread_unix.cpp
@@ -105,6 +105,7 @@ void QThreadInstance::init(unsigned int stackSize)
finished = FALSE;
running = FALSE;
orphan = FALSE;
+ disableThreadPostedEvents = FALSE;
pthread_cond_init(&thread_done, NULL);
thread_id = 0;
@@ -130,6 +131,9 @@ void *QThreadInstance::start( void *_arg )
((QThreadInstance*)arg[1])->thread_id = pthread_self();
#endif // QT_USE_GLIBMAINLOOP
+#ifdef QT_DEBUG
+ qDebug("QThreadInstance::start: Setting thread storage to %p\n\r", (QThread *) arg[0]);
+#endif // QT_DEBUG
setCurrentThread( (QThread *) arg[0] );
pthread_cleanup_push( QThreadInstance::finish, arg[1] );
@@ -152,6 +156,8 @@ void QThreadInstance::finish( void * )
return;
}
+ qDebug("QThreadInstance::finish: In QThreadInstance::finish for thread %p\n\r", (QThread*)d->args[0]);
+
QApplication::threadTerminationHandler((QThread*)d->args[0]);
QMutexLocker locker( d->mutex() );
@@ -510,7 +516,7 @@ bool QThread::wait( unsigned long time )
\sa CleanupType
*/
-QThread::CleanupType QThread::cleanupType() {
+QThread::CleanupType QThread::cleanupType() const {
return (QThread::CleanupType)d->cleanupType;
}
diff --git a/src/tools/qthreadinstance_p.h b/src/tools/qthreadinstance_p.h
index 34550a8..87dbe6c 100644
--- a/src/tools/qthreadinstance_p.h
+++ b/src/tools/qthreadinstance_p.h
@@ -102,6 +102,7 @@ public:
QEventLoop* eventLoop;
int cleanupType;
+ bool disableThreadPostedEvents : 1;
};
#endif // QT_THREAD_SUPPORT
diff --git a/tutorial/t15/main.cpp b/tutorial/t15/main.cpp
index 61febaa..72736df 100644
--- a/tutorial/t15/main.cpp
+++ b/tutorial/t15/main.cpp
@@ -57,11 +57,11 @@ void MainObject::buttonClicked()
eventLoop->exit(0);
}
-#define SET_UP_WORKER(x, y, z) \
- WorkerObject x; \
- x.threadFriendlyName = y; \
- x.moveToThread(&z); \
- QObject::connect(&x, SIGNAL(displayMessage(QString,QString)), &mainobject, SLOT(emitMessage(QString,QString))); \
+#define SET_UP_WORKER(x, y, z) \
+ WorkerObject x; \
+ x.threadFriendlyName = y; \
+ x.moveToThread(&z); \
+ QObject::connect(&x, SIGNAL(displayMessage(QString,QString)), &mainobject, SLOT(emitMessage(QString,QString))); \
QTimer::singleShot(0, &x, SLOT(run()));
int main( int argc, char **argv )