PluginManager: Introduce global future synchronizer

The global synchronizer will be destructed after the
asynchronous shutdown phase and prior to deleting
all the plugins (i.e. synchronously). It's assumed that
between deleting the synchronizer and the point when all
plugin destructors are finished no new futures are added
to the global future synchronizer.

Change-Id: Ibc839b04f2c2bbd35980b8baed51b29c2c4f7c76
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Jarek Kobus
2023-04-25 14:07:03 +02:00
parent e03081a008
commit 72bddf9f51
3 changed files with 15 additions and 0 deletions

View File

@@ -32,6 +32,7 @@
#include <utils/benchmarker.h> #include <utils/benchmarker.h>
#include <utils/executeondestruction.h> #include <utils/executeondestruction.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/futuresynchronizer.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/mimeutils.h> #include <utils/mimeutils.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -422,6 +423,11 @@ QString PluginManager::systemInformation()
return result; return result;
} }
static FutureSynchronizer *futureSynchronizer()
{
return d->m_futureSynchronizer.get();
}
/*! /*!
The list of paths were the plugin manager searches for plugins. The list of paths were the plugin manager searches for plugins.
@@ -976,6 +982,8 @@ void PluginManagerPrivate::nextDelayedInitialize()
PluginManagerPrivate::PluginManagerPrivate(PluginManager *pluginManager) : PluginManagerPrivate::PluginManagerPrivate(PluginManager *pluginManager) :
q(pluginManager) q(pluginManager)
{ {
m_futureSynchronizer.reset(new FutureSynchronizer);
m_futureSynchronizer->setCancelOnWait(true);
} }
@@ -1043,6 +1051,7 @@ void PluginManagerPrivate::stopAll()
*/ */
void PluginManagerPrivate::deleteAll() void PluginManagerPrivate::deleteAll()
{ {
m_futureSynchronizer.reset(); // Synchronize all futures from all plugins
Utils::reverseForeach(loadQueue(), [this](PluginSpec *spec) { Utils::reverseForeach(loadQueue(), [this](PluginSpec *spec) {
loadPlugin(spec, PluginSpec::Deleted); loadPlugin(spec, PluginSpec::Deleted);
}); });

View File

@@ -15,6 +15,8 @@ QT_BEGIN_NAMESPACE
class QTextStream; class QTextStream;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Utils { class FutureSynchronizer; }
namespace ExtensionSystem { namespace ExtensionSystem {
class IPlugin; class IPlugin;
class PluginSpec; class PluginSpec;
@@ -133,6 +135,8 @@ public:
static QString systemInformation(); static QString systemInformation();
static Utils::FutureSynchronizer *futureSynchronizer();
signals: signals:
void objectAdded(QObject *obj); void objectAdded(QObject *obj);
void aboutToRemoveObject(QObject *obj); void aboutToRemoveObject(QObject *obj);

View File

@@ -26,6 +26,7 @@ class QEventLoop;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Utils { namespace Utils {
class FutureSynchronizer;
class QtcSettings; class QtcSettings;
} }
@@ -133,6 +134,7 @@ public:
QWaitCondition m_scenarioWaitCondition; QWaitCondition m_scenarioWaitCondition;
PluginManager::ProcessData m_creatorProcessData; PluginManager::ProcessData m_creatorProcessData;
std::unique_ptr<Utils::FutureSynchronizer> m_futureSynchronizer;
private: private:
PluginManager *q; PluginManager *q;