summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp7
-rw-r--r--src/corelib/thread/qthread.cpp1
-rw-r--r--src/corelib/thread/qthread_p.h1
-rw-r--r--src/corelib/thread/qthread_unix.cpp5
-rw-r--r--src/corelib/thread/qthread_win.cpp5
-rw-r--r--tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp12
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"