Python: Don't leak running futures on shutdown

This patch fixes the following assert on shutdown:
"Shutting down while process /testenv/bin/python is running\"\n".

Change-Id: I4c32ead5e4952b69ffc6037739fd417a632eda1a
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Jarek Kobus
2023-04-04 13:39:56 +02:00
parent f019dd14e0
commit 031f51794a
3 changed files with 23 additions and 12 deletions

View File

@@ -16,9 +16,11 @@
#include <projectexplorer/taskhub.h> #include <projectexplorer/taskhub.h>
#include <utils/fsengine/fileiconprovider.h> #include <utils/fsengine/fileiconprovider.h>
#include <utils/futuresynchronizer.h>
#include <utils/theme/theme.h> #include <utils/theme/theme.h>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils;
namespace Python::Internal { namespace Python::Internal {
@@ -34,6 +36,7 @@ public:
PySideBuildConfigurationFactory buildConfigFactory; PySideBuildConfigurationFactory buildConfigFactory;
SimpleTargetRunnerFactory runWorkerFactory{{runConfigFactory.runConfigurationId()}}; SimpleTargetRunnerFactory runWorkerFactory{{runConfigFactory.runConfigurationId()}};
PythonSettings settings; PythonSettings settings;
FutureSynchronizer m_futureSynchronizer;
}; };
PythonPlugin::PythonPlugin() PythonPlugin::PythonPlugin()
@@ -52,6 +55,12 @@ PythonPlugin *PythonPlugin::instance()
return m_instance; return m_instance;
} }
FutureSynchronizer *PythonPlugin::futureSynchronizer()
{
QTC_ASSERT(m_instance, return nullptr);
return &m_instance->d->m_futureSynchronizer;
}
void PythonPlugin::initialize() void PythonPlugin::initialize()
{ {
d = new PythonPluginPrivate; d = new PythonPluginPrivate;
@@ -62,9 +71,9 @@ void PythonPlugin::initialize()
void PythonPlugin::extensionsInitialized() void PythonPlugin::extensionsInitialized()
{ {
// Add MIME overlay icons (these icons displayed at Project dock panel) // Add MIME overlay icons (these icons displayed at Project dock panel)
QString imageFile = Utils::creatorTheme()->imageFile(Utils::Theme::IconOverlayPro, const QString imageFile = Utils::creatorTheme()->imageFile(Theme::IconOverlayPro,
::Constants::FILEOVERLAY_PY); ::Constants::FILEOVERLAY_PY);
Utils::FileIconProvider::registerIconOverlayForSuffix(imageFile, "py"); FileIconProvider::registerIconOverlayForSuffix(imageFile, "py");
TaskHub::addCategory(PythonErrorTaskCategory, "Python", true); TaskHub::addCategory(PythonErrorTaskCategory, "Python", true);
} }

View File

@@ -5,6 +5,8 @@
#include <extensionsystem/iplugin.h> #include <extensionsystem/iplugin.h>
namespace Utils { class FutureSynchronizer; }
namespace Python::Internal { namespace Python::Internal {
class PythonPlugin final : public ExtensionSystem::IPlugin class PythonPlugin final : public ExtensionSystem::IPlugin
@@ -17,6 +19,7 @@ public:
~PythonPlugin() final; ~PythonPlugin() final;
static PythonPlugin *instance(); static PythonPlugin *instance();
static Utils::FutureSynchronizer *futureSynchronizer();
private: private:
void initialize() final; void initialize() final;

View File

@@ -9,6 +9,7 @@
#include "pysideuicextracompiler.h" #include "pysideuicextracompiler.h"
#include "pythonconstants.h" #include "pythonconstants.h"
#include "pythonlanguageclient.h" #include "pythonlanguageclient.h"
#include "pythonplugin.h"
#include "pythonproject.h" #include "pythonproject.h"
#include "pythonsettings.h" #include "pythonsettings.h"
#include "pythontr.h" #include "pythontr.h"
@@ -31,6 +32,7 @@
#include <utils/aspects.h> #include <utils/aspects.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/futuresynchronizer.h>
#include <utils/layoutbuilder.h> #include <utils/layoutbuilder.h>
#include <utils/outputformatter.h> #include <utils/outputformatter.h>
#include <utils/theme/theme.h> #include <utils/theme/theme.h>
@@ -241,15 +243,12 @@ void PythonRunConfigurationPrivate::checkForPySide(const FilePath &python,
{ {
const PipPackage package(pySidePackageName); const PipPackage package(pySidePackageName);
QObject::disconnect(m_watcherConnection); QObject::disconnect(m_watcherConnection);
m_watcherConnection = QObject::connect(&m_watcher, m_watcherConnection = QObject::connect(&m_watcher, &QFutureWatcherBase::finished, q, [=] {
&QFutureWatcher<PipPackageInfo>::finished, handlePySidePackageInfo(m_watcher.result(), python, pySidePackageName);
q,
[=]() {
handlePySidePackageInfo(m_watcher.result(),
python,
pySidePackageName);
}); });
m_watcher.setFuture(Pip::instance(python)->info(package)); const auto future = Pip::instance(python)->info(package);
m_watcher.setFuture(future);
PythonPlugin::futureSynchronizer()->addFuture(future);
} }
void PythonRunConfigurationPrivate::handlePySidePackageInfo(const PipPackageInfo &pySideInfo, void PythonRunConfigurationPrivate::handlePySidePackageInfo(const PipPackageInfo &pySideInfo,