path: root/src
diff options
authorThiago Macieira <>2016-05-02 22:01:38 -0700
committerJake Petroules <>2016-06-02 22:16:47 +0000
commit3ec57107cedb154f256e3ad001ea5475cc64fa94 (patch)
tree1ef002d247ae853b89cdfc790f4c7d42ab21e767 /src
parent49e49bdbe16734c24407d10f86eece3d9317cc51 (diff)
Windows: stop using _beginthreadex on regular builds
This commit also reverts fecaa6aae83a3ffa8f1fd41c5aa8275a1bfa7c9b. The Microsoft documentation says _beginthreadex and _endthreadex are used to initialize the C/C++ runtime and are necessary when linking to libcmt(d).lib (that is, when using the -MT or -MTd options). For regular builds linking against the .dll runtime, there should be no impact. Inspection of the CRT source code which gets installed with Visual Studio or Windows SDK proves that. It's preferable to use CreateThread directly as _endthreadex will try to call FreeLibraryAndExitThread, which can cause a deadlock if we try to wait for the thread to exit from a global destructor. For -MT builds, since there can be no DLLs, it's not a problem to continue to use _beginthreadex and follow Microsoft's recommendation. Task-number: QTBUG-53031 Change-Id: Id5480807d25e49e78b79ffff144af62c3c59dfe0 Reviewed-by: Maurice Kalinowski <> Reviewed-by: Friedemann Kleint <>
Diffstat (limited to 'src')
2 files changed, 13 insertions, 37 deletions
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index 74e191f889..a14c193bad 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -482,7 +482,6 @@ void QThread::start(Priority priority)
d->returnCode = 0;
d->interruptionRequested = false;
-#ifndef Q_OS_WINRT
NOTE: we create the thread in the suspended state, set the
priority and then resume the thread.
@@ -493,9 +492,21 @@ void QThread::start(Priority priority)
less than NormalPriority), but the newly created thread preempts
its 'parent' and runs at normal priority.
+#if defined(Q_CC_MSVC) && !defined(_DLL) // && !defined(Q_OS_WINRT)
+# ifdef Q_OS_WINRT
+ // If you wish to accept the memory leaks, uncomment the part above.
+ // See:
+ //
+ //
+# error "Microsoft documentation says this combination leaks memory every time a thread is started. " \
+ "Please change your build back to -MD/-MDd or, if you understand this issue and want to continue, " \
+ "edit this source file."
+# endif
+ // MSVC -MT or -MTd build
d->handle = (Qt::HANDLE) _beginthreadex(NULL, d->stackSize, QThreadPrivate::start,
this, CREATE_SUSPENDED, &(d->id));
-#else // !Q_OS_WINRT
+ // MSVC -MD or -MDd or MinGW build
d->handle = (Qt::HANDLE) CreateThread(NULL, d->stackSize, (LPTHREAD_START_ROUTINE)QThreadPrivate::start,
this, CREATE_SUSPENDED, reinterpret_cast<LPDWORD>(&d->id));
#endif // Q_OS_WINRT
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index bd25d8a6bf..cddb7dfb95 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -69,10 +69,6 @@
-#ifdef Q_OS_WIN
-static void preventDllUnload();
Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager)
// can be replaced with a lambda in Qt 5.7
@@ -161,10 +157,6 @@ QDBusConnectionManager::QDBusConnectionManager()
this, &QDBusConnectionManager::createServer, Qt::BlockingQueuedConnection);
moveToThread(this); // ugly, don't do this in other projects
-#ifdef Q_OS_WIN
- // prevent the library from being unloaded on Windows. See comments in the function.
- preventDllUnload();
defaultBuses[0] = defaultBuses[1] = Q_NULLPTR;
@@ -1290,31 +1282,4 @@ QT_END_NAMESPACE
#include "qdbusconnection.moc"
-#ifdef Q_OS_WIN
-# include <qt_windows.h>
-static void preventDllUnload()
- // Thread termination is really wacky on Windows. For some reason we don't
- // understand, exiting from the thread may try to unload the DLL. Since the
- // QDBusConnectionManager thread runs until the DLL is unloaded, we've got
- // a deadlock: the main thread is waiting for the manager thread to exit,
- // but the manager thread is attempting to acquire a lock to unload the DLL.
- //
- // We work around the issue by preventing the unload from happening in the
- // first place.
- //
- // For this trick, see
- //
- static HMODULE self;
- reinterpret_cast<const wchar_t *>(&self), // any address in this DLL
- &self);
#endif // QT_NO_DBUS