diff options
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 7 | ||||
-rw-r--r-- | src/corelib/thread/qthread.cpp | 1 | ||||
-rw-r--r-- | src/corelib/thread/qthread_p.h | 1 | ||||
-rw-r--r-- | src/corelib/thread/qthread_unix.cpp | 5 | ||||
-rw-r--r-- | src/corelib/thread/qthread_win.cpp | 5 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp | 12 |
6 files changed, 24 insertions, 7 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 1696aeb77b..46de52ec9f 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -300,13 +300,6 @@ struct QCoreApplicationData { #ifndef QT_NO_LIBRARY delete app_libpaths; #endif - - // cleanup the QAdoptedThread created for the main() thread - if (QCoreApplicationPrivate::theMainThread) { - QThreadData *data = QThreadData::get2(QCoreApplicationPrivate::theMainThread); - QCoreApplicationPrivate::theMainThread = 0; - data->deref(); // deletes the data and the adopted thread - } } #ifdef Q_OS_BLACKBERRY diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index bd8c6341c1..79199c97e0 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -76,6 +76,7 @@ QThreadData::~QThreadData() // the problem... if (this->thread == QCoreApplicationPrivate::theMainThread) { QCoreApplicationPrivate::theMainThread = 0; + QThreadData::clearCurrentThreadData(); } QThread *t = thread; diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index 526633cafa..2cf988260f 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -223,6 +223,7 @@ public: ~QThreadData(); static QThreadData *current(); + static void clearCurrentThreadData(); static QThreadData *get2(QThread *thread) { Q_ASSERT_X(thread != 0, "QThread", "internal error"); return thread->d_func()->data; } diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 8104cc8938..44ad8d3ac2 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -204,6 +204,11 @@ static void clear_thread_data() pthread_setspecific(current_thread_data_key, 0); } +void QThreadData::clearCurrentThreadData() +{ + clear_thread_data(); +} + QThreadData *QThreadData::current() { QThreadData *data = get_thread_data(); diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index 8614330d6f..0cf903bb3a 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -96,6 +96,11 @@ Q_DESTRUCTOR_FUNCTION(qt_free_tls) /* QThreadData */ +void QThreadData::clearCurrentThreadData() +{ + TlsSetValue(qt_current_thread_data_tls_index, 0); +} + QThreadData *QThreadData::current() { qt_create_tls(); diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index 42bf9eeca3..10c00e2a67 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -769,6 +769,18 @@ void tst_QCoreApplication::testQuitLock() app.exec(); } +static void createQObjectOnDestruction() +{ + // Make sure that we can create a QObject after the last QObject has been + // destroyed (especially after QCoreApplication has). + // + // Before the fixes, this would cause a dangling pointer dereference. If + // the problem comes back, it's possible that the following causes no + // effect. + QObject obj; + obj.thread()->setProperty("testing", 1); +} +Q_DESTRUCTOR_FUNCTION(createQObjectOnDestruction) QTEST_APPLESS_MAIN(tst_QCoreApplication) #include "tst_qcoreapplication.moc" |