diff --git a/src/plugins/coreplugin/ssh/sshconnection.cpp b/src/plugins/coreplugin/ssh/sshconnection.cpp index 4f5b54f2f3454f23d5fd024f4693d85842f2d9d1..253c949855e540fe63fa7b97696eae6d0674b38e 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 767148769f400da71c2c90d405bf45735a0748ce..cc2338470169c87a06547bb951d7703fc6a9cf45 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 580b1d1f7d1bce459daf7623a0ab59cf771dd81e..6dbc6b207303506254b844895a002ffaabc95136 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 cf22c51f9d24be7d0a02ac5de1cc2e55fadf7925..04e2e5da0b4bae5813b909539f3485399646ecd5 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 3d2b8a09a129fef8aec9c3a4cd648596acc383d1..f156f6a0868d035f7d8e934d72698cdaa1300365 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 ce7358e91f6efcf5af0f7dbbd65809cb1cd3ae10..112f2c4bb15f2fa7a6a2c57c7c5a0b556a5ece64 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;