forked from qt-creator/qt-creator
VcsCommandDecorator: Don't leak future objects
Don't leak QFutureInterface<void> and QFutureWatcher<void> in case VcsCommandDecorator was destroyed before the task was finished. Change-Id: Ib915afe29250f3e5c3fe2e1d465005a0c980252b Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
@@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QFutureWatcher>
|
#include <QFutureInterface>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
@@ -81,12 +81,14 @@ class VcsCommandDecorator : public QObject
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VcsCommandDecorator(ShellCommand *command);
|
VcsCommandDecorator(ShellCommand *command);
|
||||||
|
~VcsCommandDecorator();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addTask(const QFuture<void> &future);
|
void addTask(const QFuture<void> &future);
|
||||||
void postRunCommand(const FilePath &workingDirectory);
|
void postRunCommand(const FilePath &workingDirectory);
|
||||||
|
|
||||||
ShellCommand *m_command;
|
ShellCommand *m_command;
|
||||||
|
QFutureInterface<void> m_futureInterface;
|
||||||
};
|
};
|
||||||
|
|
||||||
VcsCommandDecorator::VcsCommandDecorator(ShellCommand *command)
|
VcsCommandDecorator::VcsCommandDecorator(ShellCommand *command)
|
||||||
@@ -121,7 +123,13 @@ VcsCommandDecorator::VcsCommandDecorator(ShellCommand *command)
|
|||||||
connect(ICore::instance(), &ICore::coreAboutToClose, this, [this, connection] {
|
connect(ICore::instance(), &ICore::coreAboutToClose, this, [this, connection] {
|
||||||
disconnect(connection);
|
disconnect(connection);
|
||||||
m_command->abort();
|
m_command->abort();
|
||||||
});}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
VcsCommandDecorator::~VcsCommandDecorator()
|
||||||
|
{
|
||||||
|
m_futureInterface.reportFinished();
|
||||||
|
}
|
||||||
|
|
||||||
void VcsCommandDecorator::addTask(const QFuture<void> &future)
|
void VcsCommandDecorator::addTask(const QFuture<void> &future)
|
||||||
{
|
{
|
||||||
@@ -133,18 +141,7 @@ void VcsCommandDecorator::addTask(const QFuture<void> &future)
|
|||||||
if (m_command->hasProgressParser()) {
|
if (m_command->hasProgressParser()) {
|
||||||
ProgressManager::addTask(future, name, id);
|
ProgressManager::addTask(future, name, id);
|
||||||
} else {
|
} else {
|
||||||
// add a timed tasked based on timeout
|
ProgressManager::addTimedTask(m_futureInterface, name, id, qMax(2, m_command->timeoutS() / 5));
|
||||||
// we cannot access the future interface directly, so we need to create a new one
|
|
||||||
// with the same lifetime
|
|
||||||
auto fi = new QFutureInterface<void>();
|
|
||||||
auto watcher = new QFutureWatcher<void>();
|
|
||||||
connect(watcher, &QFutureWatcherBase::finished, [fi, watcher] {
|
|
||||||
fi->reportFinished();
|
|
||||||
delete fi;
|
|
||||||
watcher->deleteLater();
|
|
||||||
});
|
|
||||||
watcher->setFuture(future);
|
|
||||||
ProgressManager::addTimedTask(*fi, name, id, qMax(2, m_command->timeoutS() / 5));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Internal::VcsPlugin::addFuture(future);
|
Internal::VcsPlugin::addFuture(future);
|
||||||
|
Reference in New Issue
Block a user