From f678fce3a6e966254cfdec76ab4f594930a00c4f Mon Sep 17 00:00:00 2001 From: ck <qt-info@nokia.com> Date: Mon, 10 May 2010 11:01:56 +0200 Subject: [PATCH] SSH: Make interface more Qt-ish. --- src/plugins/coreplugin/ssh/sshconnection.cpp | 26 ++++++++++++-- src/plugins/coreplugin/ssh/sshconnection.h | 3 +- src/plugins/debugger/gdb/remotegdbprocess.cpp | 35 ++++++++++--------- src/plugins/debugger/gdb/remotegdbprocess.h | 6 ++-- .../qt-maemo/maemosshthread.cpp | 8 +++-- .../qt-maemo/maemosshthread.h | 2 +- 6 files changed, 54 insertions(+), 26 deletions(-) diff --git a/src/plugins/coreplugin/ssh/sshconnection.cpp b/src/plugins/coreplugin/ssh/sshconnection.cpp index 4f5b54f2f34..253c949855e 100644 --- a/src/plugins/coreplugin/ssh/sshconnection.cpp +++ b/src/plugins/coreplugin/ssh/sshconnection.cpp @@ -151,6 +151,9 @@ struct InteractiveSshConnectionPrivate GenericSshConnection conn; ConnectionOutputReader *outputReader; + QByteArray remoteOutput; + QMutex mutex; + QWaitCondition waitCond; }; struct NonInteractiveSshConnectionPrivate @@ -208,8 +211,12 @@ private: m_mutex.unlock(); QScopedPointer<char, QScopedPointerArrayDeleter<char> > output(m_conn->d->conn.ssh->readAndReset(channel, alloc)); - if (output) - emit m_conn->remoteOutput(QByteArray(output.data())); + if (output) { + m_conn->d->mutex.lock(); + m_conn->d->remoteOutput += output.data(); + emit m_conn->remoteOutputAvailable(); + m_conn->d->mutex.unlock(); + } } } @@ -266,10 +273,25 @@ bool InteractiveSshConnection::sendInput(const QByteArray &input) void InteractiveSshConnection::quit() { + d->mutex.lock(); + d->waitCond.wakeOne(); + d->mutex.unlock(); d->outputReader->stop(); d->conn.quit(); } +QByteArray InteractiveSshConnection::waitForRemoteOutput(int msecs) +{ + d->mutex.lock(); + if (d->remoteOutput.isEmpty()) + d->waitCond.wait(&d->mutex, msecs == -1 ? ULONG_MAX : msecs); + const QByteArray remoteOutput = d->remoteOutput; + d->remoteOutput.clear(); + d->mutex.unlock(); + return remoteOutput; +} + + InteractiveSshConnection::Ptr InteractiveSshConnection::create(const SshServerInfo &server) { return Ptr(new InteractiveSshConnection(server)); diff --git a/src/plugins/coreplugin/ssh/sshconnection.h b/src/plugins/coreplugin/ssh/sshconnection.h index 767148769f4..cc233847016 100644 --- a/src/plugins/coreplugin/ssh/sshconnection.h +++ b/src/plugins/coreplugin/ssh/sshconnection.h @@ -82,12 +82,13 @@ public: bool start(); void quit(); bool sendInput(const QByteArray &input); // Should normally end in newline. + QByteArray waitForRemoteOutput(int msecs = -1); bool hasError() const; QString error() const; ~InteractiveSshConnection(); signals: - void remoteOutput(const QByteArray &output); + void remoteOutputAvailable(); private: InteractiveSshConnection(const SshServerInfo &server); diff --git a/src/plugins/debugger/gdb/remotegdbprocess.cpp b/src/plugins/debugger/gdb/remotegdbprocess.cpp index 580b1d1f7d1..6dbc6b20730 100644 --- a/src/plugins/debugger/gdb/remotegdbprocess.cpp +++ b/src/plugins/debugger/gdb/remotegdbprocess.cpp @@ -71,12 +71,12 @@ void RemoteGdbProcess::start(const QString &cmd, const QStringList &args) return; m_command = cmd; m_cmdArgs = args; - connect(m_gdbConn.data(), SIGNAL(remoteOutput(QByteArray)), - this, SLOT(handleGdbOutput(QByteArray))); - connect(m_appOutputConn.data(), SIGNAL(remoteOutput(QByteArray)), - this, SLOT(handleAppOutput(QByteArray))); - connect(m_errOutputConn.data(), SIGNAL(remoteOutput(QByteArray)), - this, SLOT(handleErrOutput(QByteArray))); + connect(m_gdbConn.data(), SIGNAL(remoteOutputAvailable()), + this, SLOT(handleGdbOutput())); + connect(m_appOutputConn.data(), SIGNAL(remoteOutputAvailable()), + this, SLOT(handleAppOutput())); + connect(m_errOutputConn.data(), SIGNAL(remoteOutputAvailable()), + this, SLOT(handleErrOutput())); m_gdbConn->start(); m_errOutputConn->start(); m_appOutputConn->start(); @@ -130,7 +130,7 @@ QString RemoteGdbProcess::errorString() const return m_gdbConn ? m_gdbConn->error() : QString(); } -void RemoteGdbProcess::handleGdbOutput(const QByteArray &output) +void RemoteGdbProcess::handleGdbOutput() { #if 0 qDebug("%s: output is '%s'", Q_FUNC_INFO, output.data()); @@ -139,7 +139,8 @@ void RemoteGdbProcess::handleGdbOutput(const QByteArray &output) if (m_gdbState == CmdNotYetSent) return; - m_currentGdbOutput += removeCarriageReturn(output); + m_currentGdbOutput + += removeCarriageReturn(m_gdbConn->waitForRemoteOutput(0)); if (!m_currentGdbOutput.endsWith('\n')) return; @@ -217,15 +218,17 @@ qint64 RemoteGdbProcess::sendInput(const QByteArray &data) return m_gdbConn->sendInput(data) ? data.size() : 0; } -void RemoteGdbProcess::handleAppOutput(const QByteArray &output) +void RemoteGdbProcess::handleAppOutput() { + const QByteArray output = m_appOutputConn->waitForRemoteOutput(0); if (!handleAppOrErrOutput(m_appOutputConn, m_appOutputReaderState, m_initialAppOutput, AppOutputFile, output)) m_adapter->handleApplicationOutput(output); } -void RemoteGdbProcess::handleErrOutput(const QByteArray &output) +void RemoteGdbProcess::handleErrOutput() { + const QByteArray output = m_errOutputConn->waitForRemoteOutput(0); if (!handleAppOrErrOutput(m_errOutputConn, m_errOutputReaderState, m_initialErrOutput, ErrOutputFile, output)) { m_errorOutput += output; @@ -277,14 +280,14 @@ void RemoteGdbProcess::startGdb() void RemoteGdbProcess::stopReaders() { if (m_appOutputConn) { - disconnect(m_appOutputConn.data(), SIGNAL(remoteOutput(QByteArray)), - this, SLOT(handleAppOutput(QByteArray))); + disconnect(m_appOutputConn.data(), SIGNAL(remoteOutputAvailable()), + this, SLOT(handleAppOutput())); m_appOutputConn->sendInput(CtrlC); m_appOutputConn->quit(); } if (m_errOutputConn) { - disconnect(m_errOutputConn.data(), SIGNAL(remoteOutput(QByteArray)), - this, SLOT(handleErrOutput(QByteArray))); + disconnect(m_errOutputConn.data(), SIGNAL(remoteOutputAvailable()), + this, SLOT(handleErrOutput())); m_errOutputConn->sendInput(CtrlC); m_errOutputConn->quit(); } @@ -316,8 +319,8 @@ void RemoteGdbProcess::checkForGdbExit(QByteArray &output) const QByteArray exitString("^exit"); const int exitPos = output.indexOf(exitString); if (exitPos != -1) { - disconnect(m_gdbConn.data(), SIGNAL(remoteOutput(QByteArray)), - this, SLOT(handleGdbOutput(QByteArray))); + disconnect(m_gdbConn.data(), SIGNAL(remoteOutputAvailable()), + this, SLOT(handleGdbOutput())); output.remove(exitPos + exitString.size(), output.size()); stopReaders(); emit finished(0, QProcess::NormalExit); diff --git a/src/plugins/debugger/gdb/remotegdbprocess.h b/src/plugins/debugger/gdb/remotegdbprocess.h index cf22c51f9d2..04e2e5da0b4 100644 --- a/src/plugins/debugger/gdb/remotegdbprocess.h +++ b/src/plugins/debugger/gdb/remotegdbprocess.h @@ -68,9 +68,9 @@ public: static const QByteArray CtrlC; private slots: - void handleGdbOutput(const QByteArray &output); - void handleAppOutput(const QByteArray &output); - void handleErrOutput(const QByteArray &output); + void handleGdbOutput(); + void handleAppOutput(); + void handleErrOutput(); private: enum CmdState { CmdNotYetSent, CmdSent, CmdReceived }; diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemosshthread.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemosshthread.cpp index 3d2b8a09a12..f156f6a0868 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemosshthread.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemosshthread.cpp @@ -102,8 +102,8 @@ MaemoSshRunner::MaemoSshRunner(const Core::SshServerInfo &server, bool MaemoSshRunner::runInternal() { createConnection(); - connect(m_connection.data(), SIGNAL(remoteOutput(QByteArray)), - this, SLOT(handleRemoteOutput(QByteArray))); + connect(m_connection.data(), SIGNAL(remoteOutputAvailable()), + this, SLOT(handleRemoteOutput())); m_endMarkerCount = 0; m_promptEncountered = false; if (!m_connection->start()) @@ -115,8 +115,10 @@ bool MaemoSshRunner::runInternal() return !m_connection->hasError(); } -void MaemoSshRunner::handleRemoteOutput(const QByteArray &output) +void MaemoSshRunner::handleRemoteOutput() { + const QByteArray output = m_connection->waitForRemoteOutput(0); + // Wait for a prompt before sending the command. if (!m_promptEncountered) { if (output.indexOf(m_prompt) != -1) { diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemosshthread.h b/src/plugins/qt4projectmanager/qt-maemo/maemosshthread.h index ce7358e91f6..112f2c4bb15 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemosshthread.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemosshthread.h @@ -96,7 +96,7 @@ signals: private: virtual bool runInternal(); - Q_SLOT void handleRemoteOutput(const QByteArray &output); + Q_SLOT void handleRemoteOutput(); static const QByteArray EndMarker; -- GitLab