diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2016-04-27 23:44:57 -0700 |
---|---|---|
committer | Roland Winklmeier <Roland.M.Winklmeier@gmail.com> | 2016-05-02 20:24:24 +0000 |
commit | fecaa6aae83a3ffa8f1fd41c5aa8275a1bfa7c9b (patch) | |
tree | 895a0be810b6dd8b18122844ac454ca380e360bc /src/dbus | |
parent | 22a7edd816b417daf43e3b4c4f0257fbc3ad7921 (diff) | |
download | qtbase-fecaa6aae83a3ffa8f1fd41c5aa8275a1bfa7c9b.tar.gz |
Workaround Windows DLL unload issue with threads running
We don't know why it happens, so let's apply a workaround. See the
comment for more details.
Task-number: QTBUG-53031
Change-Id: Ifea6e497f11a461db432ffff144972e892fbbda5
Reviewed-by: Roland Winklmeier <Roland.M.Winklmeier@gmail.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Maurice Kalinowski <maurice.kalinowski@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/dbus')
-rw-r--r-- | src/dbus/qdbusconnection.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index 34b3da7df3..7cdacc1284 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -62,6 +62,10 @@ QT_BEGIN_NAMESPACE +#ifdef Q_OS_WIN +static void preventDllUnload(); +#endif + Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager) // can be replaced with a lambda in Qt 5.7 @@ -150,6 +154,10 @@ 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(); +#endif defaultBuses[0] = defaultBuses[1] = Q_NULLPTR; start(); } @@ -1275,4 +1283,31 @@ QT_END_NAMESPACE #include "qdbusconnection.moc" +#ifdef Q_OS_WIN +# include <qt_windows.h> + +QT_BEGIN_NAMESPACE +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 + // https://blogs.msdn.microsoft.com/oldnewthing/20131105-00/?p=2733 + + static HMODULE self; + GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_PIN, + reinterpret_cast<const wchar_t *>(&self), // any address in this DLL + &self); +} +QT_END_NAMESPACE +#endif + #endif // QT_NO_DBUS |