device: Use multiplex script to allow multithread support

Previously the runInShell and outputForRunInShell methods were
exclusively processed single threaded, meaning all calls
were processed sequentially. With the multiplexed
helper script we can now run multiple processes simultaneously.
( see tst_manual_deviceshell )

Additionally the new script allows us to capture both
stdout and stderr from commands which was not possible previously.

Change-Id: I52f4fb46d872dc274edb9c11872d2f6543741b34
Reviewed-by: David Schulz <david.schulz@qt.io>
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
Marcus Tillmanns
2022-05-13 15:13:35 +02:00
parent 13146fb0bd
commit 0135c47849
13 changed files with 937 additions and 142 deletions

View File

@@ -25,8 +25,11 @@
#include "utils_global.h"
#include <QMap>
#include <QMutex>
#include <QProcess>
#include <QThread>
#include <QWaitCondition>
#include <memory>
@@ -42,10 +45,19 @@ class QTCREATOR_UTILS_EXPORT DeviceShell : public QObject
Q_OBJECT
public:
enum class State { FailedToStart = -1, Unknown = 0, Succeeded = 1 };
struct RunResult
{
int exitCode;
QByteArray stdOutput;
int exitCode = 0;
QByteArray stdOut;
QByteArray stdErr;
};
enum class ParseType {
StdOut,
StdErr,
ExitCode,
};
DeviceShell();
@@ -54,28 +66,43 @@ public:
bool runInShell(const CommandLine &cmd, const QByteArray &stdInData = {});
RunResult outputForRunInShell(const CommandLine &cmd, const QByteArray &stdInData = {});
bool waitForStarted();
State state() const;
signals:
void done();
void errorOccurred(QProcess::ProcessError error);
protected:
bool runInShellImpl(const CommandLine &cmd, const QByteArray &stdInData = {});
RunResult outputForRunInShellImpl(const CommandLine &cmd, const QByteArray &stdInData = {});
virtual void startupFailed(const CommandLine &cmdLine);
RunResult run(const CommandLine &cmd, const QByteArray &stdInData = {});
bool start();
void close();
private:
virtual void setupShellProcess(QtcProcess *shellProcess);
virtual void startupFailed(const CommandLine &cmdLine);
bool installShellScript();
void closeShellProcess();
void onReadyRead();
private:
struct CommandRun : public RunResult
{
QWaitCondition *waiter;
};
QtcProcess *m_shellProcess = nullptr;
QThread m_thread;
int m_currentId{0};
QMutex m_commandMutex;
// QMap is used here to preserve iterators
QMap<quint64, CommandRun> m_commandOutput;
QByteArray m_commandBuffer;
State m_shellScriptState = State::Unknown;
};
} // namespace Utils