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>
This commit is contained in:
parent
22a7edd816
commit
fecaa6aae8
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user