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