Do QFutureWatcher::setFuture() after connecting to watcher's signals

Otherwise we may have race condition.
Reference: documentation for QFutureWatcher::setFuture()
and the implementation of
QFutureInterfaceBasePrivate::connectOutputInterface(
QFutureCallOutInterface *interface).

Change-Id: I5b483baaf1b844871a162f47ce7683e9ff495acb
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Jarek Kobus
2021-05-12 16:55:32 +02:00
parent 91f136ef3a
commit da27ac457f
7 changed files with 9 additions and 8 deletions

View File

@@ -377,7 +377,6 @@ FutureProgress *ProgressManagerPrivate::doAddTask(const QFuture<void> &future, c
connect(watcher, &QFutureWatcherBase::progressValueChanged, connect(watcher, &QFutureWatcherBase::progressValueChanged,
this, &ProgressManagerPrivate::updateSummaryProgressBar); this, &ProgressManagerPrivate::updateSummaryProgressBar);
connect(watcher, &QFutureWatcherBase::finished, this, &ProgressManagerPrivate::taskFinished); connect(watcher, &QFutureWatcherBase::finished, this, &ProgressManagerPrivate::taskFinished);
watcher->setFuture(future);
// handle application task // handle application task
if (flags & ShowInApplicationIcon) { if (flags & ShowInApplicationIcon) {
@@ -393,6 +392,8 @@ FutureProgress *ProgressManagerPrivate::doAddTask(const QFuture<void> &future, c
setApplicationProgressVisible(true); setApplicationProgressVisible(true);
} }
watcher->setFuture(future);
// create FutureProgress and manage task list // create FutureProgress and manage task list
removeOldTasks(type); removeOldTasks(type);
if (m_taskList.size() == 10) if (m_taskList.size() == 10)

View File

@@ -190,9 +190,9 @@ public:
command->addFlags(VcsCommand::SilentOutput | VcsCommand::SuppressFailMessage); command->addFlags(VcsCommand::SilentOutput | VcsCommand::SuppressFailMessage);
command->setProgressiveOutput(true); command->setProgressiveOutput(true);
QFutureWatcher<FileSearchResultList> watcher; QFutureWatcher<FileSearchResultList> watcher;
watcher.setFuture(m_fi.future());
connect(&watcher, &QFutureWatcher<FileSearchResultList>::canceled, connect(&watcher, &QFutureWatcher<FileSearchResultList>::canceled,
command.data(), &VcsCommand::cancel); command.data(), &VcsCommand::cancel);
watcher.setFuture(m_fi.future());
connect(command.data(), &VcsCommand::stdOutText, this, &GitGrepRunner::read); connect(command.data(), &VcsCommand::stdOutText, this, &GitGrepRunner::read);
SynchronousProcessResponse resp = command->runCommand({GitClient::instance()->vcsBinary(), arguments}, 0); SynchronousProcessResponse resp = command->runCommand({GitClient::instance()->vcsBinary(), arguments}, 0);
switch (resp.result) { switch (resp.result) {

View File

@@ -185,9 +185,9 @@ void SearchWidget::indexingStarted()
m_progress->setProgressValueAndText(1, tr("Indexing Documentation")); m_progress->setProgressValueAndText(1, tr("Indexing Documentation"));
m_progress->reportStarted(); m_progress->reportStarted();
m_watcher.setFuture(m_progress->future());
connect(&m_watcher, &QFutureWatcherBase::canceled, connect(&m_watcher, &QFutureWatcherBase::canceled,
searchEngine, &QHelpSearchEngine::cancelIndexing); searchEngine, &QHelpSearchEngine::cancelIndexing);
m_watcher.setFuture(m_progress->future());
m_queryWidget->hide(); m_queryWidget->hide();
m_indexingDocumentationLabel->show(); m_indexingDocumentationLabel->show();

View File

@@ -75,9 +75,9 @@ void SimulatorOperationDialog::addFutures(const QList<QFuture<void> > &futureLis
foreach (auto future, futureList) { foreach (auto future, futureList) {
if (!future.isFinished() || !future.isCanceled()) { if (!future.isFinished() || !future.isCanceled()) {
auto watcher = new QFutureWatcher<void>; auto watcher = new QFutureWatcher<void>;
watcher->setFuture(future);
connect(watcher, &QFutureWatcher<void>::finished, connect(watcher, &QFutureWatcher<void>::finished,
this, &SimulatorOperationDialog::futureFinished); this, &SimulatorOperationDialog::futureFinished);
watcher->setFuture(future);
m_futureWatchList << watcher; m_futureWatchList << watcher;
} }
} }

View File

@@ -113,10 +113,10 @@ QFutureWatcher<ChangeSet> *LanguageClientFormatter::format(
m_ignoreCancel = true; m_ignoreCancel = true;
m_progress.reportStarted(); m_progress.reportStarted();
auto watcher = new QFutureWatcher<ChangeSet>(); auto watcher = new QFutureWatcher<ChangeSet>();
watcher->setFuture(m_progress.future());
QObject::connect(watcher, &QFutureWatcher<Text::Replacements>::canceled, [this]() { QObject::connect(watcher, &QFutureWatcher<Text::Replacements>::canceled, [this]() {
cancelCurrentRequest(); cancelCurrentRequest();
}); });
watcher->setFuture(m_progress.future());
return watcher; return watcher;
} }

View File

@@ -162,11 +162,11 @@ QList<Core::LocatorFilterEntry> DocumentLocatorFilter::matchesFor(
QEventLoop loop; QEventLoop loop;
connect(this, &DocumentLocatorFilter::symbolsUpToDate, &loop, [&]() { loop.exit(1); }); connect(this, &DocumentLocatorFilter::symbolsUpToDate, &loop, [&]() { loop.exit(1); });
QFutureWatcher<Core::LocatorFilterEntry> watcher; QFutureWatcher<Core::LocatorFilterEntry> watcher;
watcher.setFuture(future.future());
connect(&watcher, connect(&watcher,
&QFutureWatcher<Core::LocatorFilterEntry>::canceled, &QFutureWatcher<Core::LocatorFilterEntry>::canceled,
&loop, &loop,
&QEventLoop::quit); &QEventLoop::quit);
watcher.setFuture(future.future());
locker.unlock(); locker.unlock();
if (!loop.exec()) if (!loop.exec())
return {}; return {};
@@ -263,11 +263,11 @@ QList<Core::LocatorFilterEntry> WorkspaceLocatorFilter::matchesFor(
QEventLoop loop; QEventLoop loop;
connect(this, &WorkspaceLocatorFilter::allRequestsFinished, &loop, [&]() { loop.exit(1); }); connect(this, &WorkspaceLocatorFilter::allRequestsFinished, &loop, [&]() { loop.exit(1); });
QFutureWatcher<Core::LocatorFilterEntry> watcher; QFutureWatcher<Core::LocatorFilterEntry> watcher;
watcher.setFuture(future.future());
connect(&watcher, connect(&watcher,
&QFutureWatcher<Core::LocatorFilterEntry>::canceled, &QFutureWatcher<Core::LocatorFilterEntry>::canceled,
&loop, &loop,
&QEventLoop::quit); &QEventLoop::quit);
watcher.setFuture(future.future());
locker.unlock(); locker.unlock();
if (!loop.exec()) if (!loop.exec())
return {}; return {};

View File

@@ -381,7 +381,6 @@ void PyLSConfigureAssistant::openDocumentWithPython(const FilePath &python,
using CheckPylsWatcher = QFutureWatcher<PythonLanguageServerState>; using CheckPylsWatcher = QFutureWatcher<PythonLanguageServerState>;
QPointer<CheckPylsWatcher> watcher = new CheckPylsWatcher(); QPointer<CheckPylsWatcher> watcher = new CheckPylsWatcher();
watcher->setFuture(Utils::runAsync(&checkPythonLanguageServer, python));
// cancel and delete watcher after a 10 second timeout // cancel and delete watcher after a 10 second timeout
QTimer::singleShot(10000, this, [watcher]() { QTimer::singleShot(10000, this, [watcher]() {
@@ -401,6 +400,7 @@ void PyLSConfigureAssistant::openDocumentWithPython(const FilePath &python,
handlePyLSState(python, watcher->result(), document); handlePyLSState(python, watcher->result(), document);
watcher->deleteLater(); watcher->deleteLater();
}); });
watcher->setFuture(Utils::runAsync(&checkPythonLanguageServer, python));
} }
void PyLSConfigureAssistant::handlePyLSState(const FilePath &python, void PyLSConfigureAssistant::handlePyLSState(const FilePath &python,