From 7c402ad3d15ff5e7c2b7319b1bea821f6f67e26c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 27 Sep 2016 16:52:55 -0700 Subject: [PATCH] Make the bearer QFactoryLoader a member variable, not a static Because it was a function-level static, the QFactoryLoader was getting destroyed out-of-sync with the bearer thread stopping. Under normal conditions, the thread stopped first (~QApplication / ~QCoreApplication via qAddPostRoutine), and the static got destroyed when the process exited. However, if QApplication leaked or if the destruction order is wonky (as seen in PyQt5), the thread could still be running when the plugins were already unloaded. With the loader a member variable, it gets destroyed when the thread stops. Note: in Qt 5.7, QFactoryLoader no longer unloads the plugins (since commit 494376f980e96339b6f1eff7c41336ca4d853065), so this crash cannot happen in that version. [ChangeLog][QtNetwork][Bearer management] Fixed a bug that could cause a crash on application exit, depending on the order of destruction of the QCoreApplication object and the QtDBus manager thread. Task-number: QTBUG-56228 Task-number: QTBUG-52988 Change-Id: I33dc971f005a4848bb8ffffd147853376f82de2a Reviewed-by: Lorn Potter Reviewed-by: Edward Welbourne --- src/network/bearer/qnetworkconfigmanager_p.cpp | 7 +++---- src/network/bearer/qnetworkconfigmanager_p.h | 2 ++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index 2da073fa5a2..a903ecda5fe 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -40,8 +40,6 @@ #include "qnetworkconfigmanager_p.h" #include "qbearerplugin_p.h" -#include - #include #include #include @@ -60,7 +58,9 @@ QT_BEGIN_NAMESPACE QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate() - : QObject(), pollTimer(0), mutex(QMutex::Recursive), forcedPolling(0), firstUpdate(true) + : QObject(), pollTimer(0), mutex(QMutex::Recursive), + loader(QBearerEngineFactoryInterface_iid, QLatin1String("/bearer")), + forcedPolling(0), firstUpdate(true) { qRegisterMetaType(); qRegisterMetaType(); @@ -365,7 +365,6 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations() bool envOK = false; const int skipGeneric = qEnvironmentVariableIntValue("QT_EXCLUDE_GENERIC_BEARER", &envOK); QBearerEngine *generic = 0; - static QFactoryLoader loader(QBearerEngineFactoryInterface_iid, QLatin1String("/bearer")); QFactoryLoader *l = &loader; const PluginKeyMap keyMap = l->keyMap(); const PluginKeyMapConstIterator cend = keyMap.constEnd(); diff --git a/src/network/bearer/qnetworkconfigmanager_p.h b/src/network/bearer/qnetworkconfigmanager_p.h index a804e037a30..380e25c22f7 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.h +++ b/src/network/bearer/qnetworkconfigmanager_p.h @@ -55,6 +55,7 @@ #include "qnetworkconfigmanager.h" #include "qnetworkconfiguration_p.h" +#include #include #include @@ -118,6 +119,7 @@ private: private: mutable QMutex mutex; + QFactoryLoader loader; QList sessionEngines; QSet onlineConfigurations;