1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qprocessscheduler_p.h"
#include <QtQmlDom/private/qqmldom_utils_p.h>
QT_BEGIN_NAMESPACE
namespace QmlLsp {
Q_STATIC_LOGGING_CATEGORY(schedulerLog, "qt.languageserver.qprocessscheduler")
using namespace Qt::StringLiterals;
/*!
\internal
\class QProcessScheduler
\brief Runs multiple processes sequentially via a QProcess, and signals once they are done.
QProcessScheduler runs multiple programs sequentially through a QProcess, and emits the \c done
signal once all programs finished. Use schedule(programs, id) to add new programs to be run. The
id is used to signal their completion. Duplicate programs that already are in the queue are not
re-added to the queue.
*/
QProcessScheduler::QProcessScheduler()
{
QObject::connect(&m_process, &QProcess::finished, this, &QProcessScheduler::processNext);
QObject::connect(&m_process, &QProcess::errorOccurred, this,
&QProcessScheduler::onErrorOccurred);
}
QProcessScheduler::~QProcessScheduler()
{
QObject::disconnect(&m_process, nullptr);
m_process.kill();
m_process.waitForFinished();
}
void QProcessScheduler::schedule(const QList<Command> &list, const Id &id)
{
for (const auto &x : list) {
const QueueElement queueElement{ x };
if (!m_queue.contains(queueElement))
m_queue.enqueue(queueElement);
}
m_queue.enqueue(id);
if (!m_isRunning)
processNext();
}
void QProcessScheduler::processNext()
{
m_isRunning = m_queue.size() > 0;
if (!m_isRunning)
return;
std::visit(qOverloadedVisitor{ [this](const Id &id) {
emit done(id);
processNext();
},
[this](const Command &command) {
m_process.setProgram(command.program);
m_process.setArguments(command.arguments);
m_process.setProcessEnvironment(command.customEnvironment);
m_process.start();
}
},
m_queue.dequeue());
}
void QProcessScheduler::onErrorOccurred(QProcess::ProcessError error)
{
qCDebug(schedulerLog) << "Process" << m_process.program() << m_process.arguments().join(" "_L1)
<< "had an error:" << error;
processNext();
}
} // namespace QmlLsp
QT_END_NAMESPACE
|