VcsBase: Use QtConcurrent invocation for async run

Change-Id: Ia4e461c1a2e71d4c959f582e9ed464d4713b672a
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Jarek Kobus
2023-03-04 00:39:50 +01:00
parent cae18f8872
commit ce037d09a2
6 changed files with 54 additions and 50 deletions

View File

@@ -30,13 +30,13 @@
#include <projectexplorer/projectmanager.h>
#include <utils/algorithm.h>
#include <utils/asynctask.h>
#include <utils/hostosinfo.h>
#include <utils/infobar.h>
#include <utils/layoutbuilder.h>
#include <utils/parameteraction.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <utils/runextensions.h>
#include <utils/temporarydirectory.h>
#include <vcsbase/basevcseditorfactory.h>
@@ -259,7 +259,7 @@ private:
CommandResult runCleartool(const FilePath &workingDir, const QStringList &arguments,
VcsBase::RunFlags flags = VcsBase::RunFlags::None,
QTextCodec *codec = nullptr, int timeoutMultiplier = 1) const;
static void sync(QFutureInterface<void> &future, QStringList files);
static void sync(QPromise<void> &promise, QStringList files);
void history(const FilePath &workingDir,
const QStringList &file = {},
@@ -1657,7 +1657,7 @@ bool ClearCasePluginPrivate::vcsOpen(const FilePath &workingDir, const QString &
if (!m_settings.disableIndexer &&
(fi.isWritable() || vcsStatus(absPath).status == FileStatus::Unknown))
runAsync(sync, QStringList(absPath)).waitForFinished();
Utils::asyncRun(sync, QStringList(absPath)).waitForFinished();
if (vcsStatus(absPath).status == FileStatus::CheckedOut) {
QMessageBox::information(ICore::dialogParent(), Tr::tr("ClearCase Checkout"),
Tr::tr("File is already checked out."));
@@ -2129,7 +2129,8 @@ void ClearCasePluginPrivate::updateIndex()
return;
m_checkInAllAction->setEnabled(false);
m_statusMap->clear();
QFuture<void> result = runAsync(sync, transform(project->files(Project::SourceFiles), &FilePath::toString));
QFuture<void> result = Utils::asyncRun(sync, transform(project->files(Project::SourceFiles),
&FilePath::toString));
if (!m_settings.disableIndexer)
ProgressManager::addTask(result, Tr::tr("Updating ClearCase Index"), ClearCase::Constants::TASK_INDEX);
}
@@ -2261,7 +2262,7 @@ void ClearCasePluginPrivate::syncSlot()
FilePath topLevel = state.topLevel();
if (topLevel != state.currentProjectTopLevel())
return;
runAsync(sync, QStringList());
Utils::asyncRun(sync, QStringList()); // TODO: make use of returned QFuture
}
void ClearCasePluginPrivate::closing()
@@ -2271,12 +2272,12 @@ void ClearCasePluginPrivate::closing()
disconnect(qApp, &QApplication::applicationStateChanged, nullptr, nullptr);
}
void ClearCasePluginPrivate::sync(QFutureInterface<void> &future, QStringList files)
void ClearCasePluginPrivate::sync(QPromise<void> &promise, QStringList files)
{
ClearCasePluginPrivate *plugin = ClearCasePluginPrivate::instance();
ClearCaseSync ccSync(plugin->m_statusMap);
connect(&ccSync, &ClearCaseSync::updateStreamAndView, plugin, &ClearCasePluginPrivate::updateStreamAndView);
ccSync.run(future, files);
ccSync.run(promise, files);
}
QString ClearCasePluginPrivate::displayName() const

View File

@@ -13,6 +13,8 @@
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <QPromise>
#ifdef WITH_TESTS
#include <QTest>
#include <utils/fileutils.h>
@@ -22,8 +24,7 @@ using namespace Utils;
namespace ClearCase::Internal {
static void runProcess(QFutureInterface<void> &future,
const ClearCaseSettings &settings,
static void runProcess(QPromise<void> &promise, const ClearCaseSettings &settings,
const QStringList &args,
std::function<void(const QString &buffer, int processed)> processLine)
{
@@ -37,7 +38,7 @@ static void runProcess(QFutureInterface<void> &future,
int processed = 0;
QString buffer;
while (process.waitForReadyRead() && !future.isCanceled()) {
while (process.waitForReadyRead() && !promise.isCanceled()) {
buffer += QString::fromLocal8Bit(process.readAllRawStandardOutput());
int index = buffer.indexOf('\n');
while (index != -1) {
@@ -135,7 +136,7 @@ void ClearCaseSync::updateStatusForNotManagedFiles(const QStringList &files)
}
}
void ClearCaseSync::syncSnapshotView(QFutureInterface<void> &future, QStringList &files,
void ClearCaseSync::syncSnapshotView(QPromise<void> &promise, QStringList &files,
const ClearCaseSettings &settings)
{
const QString view = ClearCasePlugin::viewData().name;
@@ -167,18 +168,18 @@ void ClearCaseSync::syncSnapshotView(QFutureInterface<void> &future, QStringList
// adding 1 for initial sync in which total is not accurate, to prevent finishing
// (we don't want it to become green)
future.setProgressRange(0, totalFileCount + 1);
promise.setProgressRange(0, totalFileCount + 1);
int totalProcessed = 0;
runProcess(future, settings, args, [&](const QString &buffer, int processed) {
runProcess(promise, settings, args, [&](const QString &buffer, int processed) {
processCleartoolLsLine(viewRootDir, buffer);
future.setProgressValue(qMin(totalFileCount, processed));
promise.setProgressValue(qMin(totalFileCount, processed));
totalProcessed = processed;
});
if (!future.isCanceled()) {
if (!promise.isCanceled()) {
updateStatusForNotManagedFiles(files);
future.setProgressValue(totalFileCount + 1);
promise.setProgressValue(totalFileCount + 1);
if (!hot)
updateTotalFilesCount(view, settings, totalProcessed);
}
@@ -193,21 +194,20 @@ void ClearCaseSync::processCleartoolLscheckoutLine(const QString &buffer)
///
/// Update the file status for dynamic views.
///
void ClearCaseSync::syncDynamicView(QFutureInterface<void> &future,
const ClearCaseSettings& settings)
void ClearCaseSync::syncDynamicView(QPromise<void> &promise, const ClearCaseSettings& settings)
{
// Always invalidate status for all files
invalidateStatusAllFiles();
const QStringList args({"lscheckout", "-avobs", "-me", "-cview", "-s"});
runProcess(future, settings, args, [&](const QString &buffer, int processed) {
runProcess(promise, settings, args, [&](const QString &buffer, int processed) {
processCleartoolLscheckoutLine(buffer);
future.setProgressValue(processed);
promise.setProgressValue(processed);
});
}
void ClearCaseSync::run(QFutureInterface<void> &future, QStringList &files)
void ClearCaseSync::run(QPromise<void> &promise, QStringList &files)
{
ClearCaseSettings settings = ClearCasePlugin::settings();
if (settings.disableIndexer)
@@ -225,9 +225,9 @@ void ClearCaseSync::run(QFutureInterface<void> &future, QStringList &files)
emit updateStreamAndView();
if (ClearCasePlugin::viewData().isDynamic)
syncDynamicView(future, settings);
syncDynamicView(promise, settings);
else
syncSnapshotView(future, files, settings);
syncSnapshotView(promise, files, settings);
}
#ifdef WITH_TESTS

View File

@@ -9,6 +9,8 @@ QT_BEGIN_NAMESPACE
class QDir;
template <typename T>
class QFutureInterface;
template <typename T>
class QPromise;
QT_END_NAMESPACE
namespace ClearCase::Internal {
@@ -18,7 +20,7 @@ class ClearCaseSync : public QObject
Q_OBJECT
public:
explicit ClearCaseSync(QSharedPointer<StatusMap> statusMap);
void run(QFutureInterface<void> &future, QStringList &files);
void run(QPromise<void> &promise, QStringList &files);
QStringList updateStatusHotFiles(const QString &viewRoot, int &total);
void invalidateStatus(const QDir &viewRootDir, const QStringList &files);
@@ -28,9 +30,8 @@ public:
const int processed);
void updateStatusForNotManagedFiles(const QStringList &files);
void syncDynamicView(QFutureInterface<void> &future,
const ClearCaseSettings &settings);
void syncSnapshotView(QFutureInterface<void> &future, QStringList &files,
void syncDynamicView(QPromise<void> &promise, const ClearCaseSettings &settings);
void syncSnapshotView(QPromise<void> &promise, QStringList &files,
const ClearCaseSettings &settings);
void processCleartoolLscheckoutLine(const QString &buffer);

View File

@@ -13,6 +13,7 @@
#include <vcsbase/vcsbaseconstants.h>
#include <utils/algorithm.h>
#include <utils/asynctask.h>
#include <utils/environment.h>
#include <utils/fancylineedit.h>
#include <utils/filesearch.h>
@@ -45,7 +46,7 @@ public:
class GitGrepRunner
{
using FutureInterfaceType = QFutureInterface<FileSearchResultList>;
using PromiseType = QPromise<FileSearchResultList>;
public:
GitGrepRunner(const TextEditor::FileFindParameters &parameters)
@@ -116,7 +117,7 @@ public:
}
}
void read(FutureInterfaceType &fi, const QString &text)
void read(PromiseType &fi, const QString &text)
{
FileSearchResultList resultList;
QString t = text;
@@ -124,10 +125,10 @@ public:
while (!stream.atEnd() && !fi.isCanceled())
processLine(stream.readLine(), &resultList);
if (!resultList.isEmpty() && !fi.isCanceled())
fi.reportResult(resultList);
fi.addResult(resultList);
}
void operator()(FutureInterfaceType &fi)
void operator()(PromiseType &promise)
{
QStringList arguments = {
"-c", "color.grep.match=bold red",
@@ -165,7 +166,7 @@ public:
process.setEnvironment(m_environment);
process.setCommand({m_vcsBinary, arguments});
process.setWorkingDirectory(m_directory);
process.setStdOutCallback([this, &fi](const QString &text) { read(fi, text); });
process.setStdOutCallback([this, &promise](const QString &text) { read(promise, text); });
process.start();
process.waitForFinished();
@@ -173,7 +174,7 @@ public:
case ProcessResult::TerminatedAbnormally:
case ProcessResult::StartFailed:
case ProcessResult::Hang:
fi.reportCanceled();
promise.future().cancel();
break;
case ProcessResult::FinishedWithSuccess:
case ProcessResult::FinishedWithError:
@@ -275,7 +276,7 @@ void GitGrep::writeSettings(QSettings *settings) const
QFuture<FileSearchResultList> GitGrep::executeSearch(const TextEditor::FileFindParameters &parameters,
TextEditor::BaseFileFind * /*baseFileFind*/)
{
return Utils::runAsync(GitGrepRunner(parameters));
return Utils::asyncRun(GitGrepRunner(parameters));
}
IEditor *GitGrep::openEditor(const SearchResultItem &item,

View File

@@ -11,8 +11,8 @@
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/iversioncontrol.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <utils/asynctask.h>
#include <utils/qtcassert.h>
#include <utils/runextensions.h>
#include <vcsbase/submitfilemodel.h>
#include <vcsbase/vcsoutputwindow.h>
@@ -204,7 +204,7 @@ void GitSubmitEditor::updateFileModel()
return;
w->setUpdateInProgress(true);
// TODO: Check if fetch works OK from separate thread, refactor otherwise
m_fetchWatcher.setFuture(Utils::runAsync(&CommitDataFetchResult::fetch,
m_fetchWatcher.setFuture(Utils::asyncRun(&CommitDataFetchResult::fetch,
m_commitType, m_workingDirectory));
Core::ProgressManager::addTask(m_fetchWatcher.future(), Tr::tr("Refreshing Commit Data"),
TASK_UPDATE_COMMIT);

View File

@@ -9,8 +9,8 @@
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <utils/asynctask.h>
#include <utils/layoutbuilder.h>
#include <utils/runextensions.h>
#include <QApplication>
#include <QCheckBox>
@@ -38,10 +38,10 @@ enum { nameColumn, columnCount };
enum { fileNameRole = Qt::UserRole, isDirectoryRole = Qt::UserRole + 1 };
// Helper for recursively removing files.
static void removeFileRecursion(QFutureInterface<void> &futureInterface,
const QFileInfo &f, QString *errorMessage)
static void removeFileRecursion(QPromise<void> &promise, const QFileInfo &f,
QString *errorMessage)
{
if (futureInterface.isCanceled())
if (promise.isCanceled())
return;
// The version control system might list files/directory in arbitrary
// order, causing files to be removed from parent directories.
@@ -51,7 +51,7 @@ static void removeFileRecursion(QFutureInterface<void> &futureInterface,
const QDir dir(f.absoluteFilePath());
const QList<QFileInfo> infos = dir.entryInfoList(QDir::AllEntries|QDir::NoDotAndDotDot|QDir::Hidden);
for (const QFileInfo &fi : infos)
removeFileRecursion(futureInterface, fi, errorMessage);
removeFileRecursion(promise, fi, errorMessage);
QDir parent = f.absoluteDir();
if (!parent.rmdir(f.fileName()))
errorMessage->append(Tr::tr("The directory %1 could not be deleted.")
@@ -67,18 +67,19 @@ static void removeFileRecursion(QFutureInterface<void> &futureInterface,
}
// Cleaning files in the background
static void runCleanFiles(QFutureInterface<void> &futureInterface,
const FilePath &repository, const QStringList &files,
static void runCleanFiles(QPromise<void> &promise, const FilePath &repository,
const QStringList &files,
const std::function<void(const QString&)> &errorHandler)
{
QString errorMessage;
futureInterface.setProgressRange(0, files.size());
futureInterface.setProgressValue(0);
promise.setProgressRange(0, files.size());
promise.setProgressValue(0);
int fileIndex = 0;
for (const QString &name : files) {
removeFileRecursion(futureInterface, QFileInfo(name), &errorMessage);
if (futureInterface.isCanceled())
removeFileRecursion(promise, QFileInfo(name), &errorMessage);
if (promise.isCanceled())
break;
futureInterface.setProgressValue(futureInterface.progressValue() + 1);
promise.setProgressValue(++fileIndex);
}
if (!errorMessage.isEmpty()) {
// Format and emit error.
@@ -258,7 +259,7 @@ bool CleanDialog::promptToDelete()
return false;
// Remove in background
QFuture<void> task = runAsync(Internal::runCleanFiles, d->m_workingDirectory,
QFuture<void> task = Utils::asyncRun(Internal::runCleanFiles, d->m_workingDirectory,
selectedFiles, Internal::handleError);
const QString taskName = Tr::tr("Cleaning \"%1\"").arg(d->m_workingDirectory.toUserOutput());