aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2024-05-16 09:29:51 +0200
committerEike Ziller <eike.ziller@qt.io>2024-05-21 09:56:32 +0000
commitc676ec825f45364421e3463021113062aad6919b (patch)
tree3cc41566eaebd7aa6301a6e0ec9d39523ff76adf /src/libs
parent3cd72806f82dc357f8c42153abc9956c3651cab6 (diff)
AsyncTask: Centralize setting global future synchronizerHEADmaster
Move the global FutureSynchronizer to Utils and use it by default for AsyncTask (if that is in the main thread). This way setting a synchronizer is less prone to be forgotten. Individual uses can still override this. Change-Id: I1a12bf4d7f4cb5be99668bf0a4797108c2fe6448 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/extensionsystem/pluginmanager.cpp15
-rw-r--r--src/libs/extensionsystem/pluginmanager_p.h1
-rw-r--r--src/libs/utils/async.h5
-rw-r--r--src/libs/utils/futuresynchronizer.cpp17
-rw-r--r--src/libs/utils/futuresynchronizer.h2
5 files changed, 31 insertions, 9 deletions
diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp
index f0c7e930b4..9aa10709be 100644
--- a/src/libs/extensionsystem/pluginmanager.cpp
+++ b/src/libs/extensionsystem/pluginmanager.cpp
@@ -17,8 +17,8 @@
#include <utils/futuresynchronizer.h>
#include <utils/hostosinfo.h>
#include <utils/mimeutils.h>
-#include <utils/qtcprocess.h>
#include <utils/qtcassert.h>
+#include <utils/qtcprocess.h>
#include <utils/qtcsettings.h>
#include <utils/threadutils.h>
@@ -436,7 +436,7 @@ QString PluginManager::systemInformation()
FutureSynchronizer *PluginManager::futureSynchronizer()
{
- return d->m_futureSynchronizer.get();
+ return Utils::futureSynchronizer();
}
/*!
@@ -981,10 +981,7 @@ void PluginManagerPrivate::startDelayedInitialize()
*/
PluginManagerPrivate::PluginManagerPrivate(PluginManager *pluginManager) :
q(pluginManager)
-{
- m_futureSynchronizer.reset(new FutureSynchronizer);
-}
-
+{}
/*!
\internal
@@ -1047,7 +1044,11 @@ void PluginManagerPrivate::stopAll()
*/
void PluginManagerPrivate::deleteAll()
{
- m_futureSynchronizer.reset(); // Synchronize all futures from all plugins
+ // Guard against someone playing with the setting
+ QTC_ASSERT(
+ Utils::futureSynchronizer()->isCancelOnWait(),
+ Utils::futureSynchronizer()->cancelAllFutures());
+ Utils::futureSynchronizer()->waitForFinished(); // Synchronize all futures from all plugins
Utils::reverseForeach(loadQueue(), [this](PluginSpec *spec) {
loadPlugin(spec, PluginSpec::Deleted);
});
diff --git a/src/libs/extensionsystem/pluginmanager_p.h b/src/libs/extensionsystem/pluginmanager_p.h
index a761614223..ad9d4f81ee 100644
--- a/src/libs/extensionsystem/pluginmanager_p.h
+++ b/src/libs/extensionsystem/pluginmanager_p.h
@@ -136,7 +136,6 @@ public:
QWaitCondition m_scenarioWaitCondition;
PluginManager::ProcessData m_creatorProcessData;
- std::unique_ptr<Utils::FutureSynchronizer> m_futureSynchronizer;
private:
PluginManager *q;
diff --git a/src/libs/utils/async.h b/src/libs/utils/async.h
index af6fb3fd85..8c7155bc13 100644
--- a/src/libs/utils/async.h
+++ b/src/libs/utils/async.h
@@ -7,6 +7,7 @@
#include "futuresynchronizer.h"
#include "qtcassert.h"
+#include "threadutils.h"
#include <solutions/tasking/tasktree.h>
@@ -130,7 +131,9 @@ template <typename ResultType>
class Async : public AsyncBase
{
public:
- Async() {
+ Async()
+ : m_synchronizer(isMainThread() ? futureSynchronizer() : nullptr)
+ {
connect(&m_watcher, &QFutureWatcherBase::finished, this, &AsyncBase::done);
connect(&m_watcher, &QFutureWatcherBase::resultReadyAt, this, &AsyncBase::resultReadyAt);
}
diff --git a/src/libs/utils/futuresynchronizer.cpp b/src/libs/utils/futuresynchronizer.cpp
index da3347f35e..912de677b9 100644
--- a/src/libs/utils/futuresynchronizer.cpp
+++ b/src/libs/utils/futuresynchronizer.cpp
@@ -3,6 +3,9 @@
#include "futuresynchronizer.h"
+#include "qtcassert.h"
+#include "threadutils.h"
+
/*!
\class Utils::FutureSynchronizer
\inmodule QtCreator
@@ -62,4 +65,18 @@ void FutureSynchronizer::flushFinishedFutures()
m_futures = newFutures;
}
+Q_GLOBAL_STATIC(FutureSynchronizer, s_futureSynchronizer);
+
+/*!
+ Returns a global FutureSynchronizer.
+ The application should cancel and wait for the tasks in this synchronizer before actually
+ unloading any libraries. This is for example done by the plugin manager in Qt Creator.
+ May only be accessed by the main thread.
+*/
+FutureSynchronizer *futureSynchronizer()
+{
+ QTC_ASSERT(isMainThread(), return nullptr);
+ return s_futureSynchronizer;
+}
+
} // namespace Utils
diff --git a/src/libs/utils/futuresynchronizer.h b/src/libs/utils/futuresynchronizer.h
index 29b1f5e456..83391dbc72 100644
--- a/src/libs/utils/futuresynchronizer.h
+++ b/src/libs/utils/futuresynchronizer.h
@@ -42,4 +42,6 @@ private:
bool m_cancelOnWait = true;
};
+QTCREATOR_UTILS_EXPORT FutureSynchronizer *futureSynchronizer();
+
} // namespace Utils