diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.cpp index 43bed218f18e28c5b78a15c0ca2e07b6b773e91d..5da1f46bef7e6283371fe3a314af65a1c1f42134 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.cpp @@ -557,6 +557,7 @@ void MaemoDeployStep::handleMounted() void MaemoDeployStep::handleUnmounted() { + m_mounter->resetMountSpecifications(); if (m_stopped) { m_canStart = true; return; @@ -574,7 +575,7 @@ void MaemoDeployStep::handleUnmounted() } else { #ifdef Q_OS_WIN bool drivesToMount[26]; - for (int i = 0; i < sizeof drivesToMount / drivesToMount[0]; ++i) + for (int i = 0; i < sizeof drivesToMount / sizeof drivesToMount[0]; ++i) drivesToMount[i] = false; for (int i = 0; i < m_filesToCopy.count(); ++i) { const QString localDir = QFileInfo(m_filesToCopy.at(i).localFilePath) diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoremotemounter.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemoremotemounter.cpp index a36b4edd362a58d3d36020b77485759cd7242101..6c06d6f127d8d8647af96efef911ade16fa4f58c 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemoremotemounter.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemoremotemounter.cpp @@ -36,7 +36,7 @@ #include <coreplugin/ssh/sshconnection.h> #include <coreplugin/ssh/sshremoteprocess.h> -#include <QtCore/QProcess> +#include <QtCore/QTimer> using namespace Core; @@ -45,12 +45,19 @@ namespace Internal { MaemoRemoteMounter::MaemoRemoteMounter(QObject *parent, const MaemoToolChain *toolchain) - : QObject(parent), m_toolChain(toolchain), m_uploadJobId(SftpInvalidJob), + : QObject(parent), m_toolChain(toolchain), + m_utfsServerTimer(new QTimer(this)), m_uploadJobId(SftpInvalidJob), m_stop(false) { + m_utfsServerTimer->setSingleShot(true); + connect(m_utfsServerTimer, SIGNAL(timeout()), this, + SLOT(handleUtfsServerTimeout())); } -MaemoRemoteMounter::~MaemoRemoteMounter() {} +MaemoRemoteMounter::~MaemoRemoteMounter() +{ + killAllUtfsServers(); +} void MaemoRemoteMounter::setConnection(const Core::SshConnection::Ptr &connection) { @@ -72,7 +79,8 @@ bool MaemoRemoteMounter::addMountSpecification(const MaemoMountSpecification &mo void MaemoRemoteMounter::mount() { m_stop = false; - Q_ASSERT(m_utfsServers.isEmpty()); + Q_ASSERT(m_startedUtfsServers.isEmpty()); + Q_ASSERT(m_readyUtfsServers.isEmpty()); if (m_mountSpecs.isEmpty()) emit mounted(); @@ -126,13 +134,7 @@ void MaemoRemoteMounter::handleUnmountProcessFinished(int exitStatus) "Impossible SshRemoteProcess exit status."); } - foreach (const ProcPtr &utfsServer, m_utfsServers) { - utfsServer->terminate(); - utfsServer->waitForFinished(1000); - utfsServer->kill(); - } - m_mountSpecs.clear(); - m_utfsServers.clear(); + killAllUtfsServers(); if (errorMsg.isEmpty()) { emit reportProgress(tr("Finished unmounting.")); @@ -274,6 +276,7 @@ void MaemoRemoteMounter::handleUtfsClientsFinished(int exitStatus) void MaemoRemoteMounter::startUtfsServers() { emit reportProgress(tr("Starting UTFS servers...")); + m_utfsServerTimer->start(30000); for (int i = 0; i < m_mountSpecs.count(); ++i) { const MountInfo &mountInfo = m_mountSpecs.at(i); const MaemoMountSpecification &mountSpec = mountInfo.mountSpec; @@ -281,29 +284,97 @@ void MaemoRemoteMounter::startUtfsServers() const QString port = QString::number(mountInfo.remotePort); const QString localSecretOpt = QLatin1String("-l"); const QString remoteSecretOpt = QLatin1String("-r"); - const QStringList utfsServerArgs = QStringList() - << QLatin1String("--detach") << localSecretOpt << port - << remoteSecretOpt << port << QLatin1String("-c") + const QStringList utfsServerArgs = QStringList() << localSecretOpt + << port << remoteSecretOpt << port << QLatin1String("-c") << (m_connection->connectionParameters().host + QLatin1Char(':') + port) << mountSpec.localDir; + connect(utfsServerProc.data(), SIGNAL(readyReadStandardError()), this, + SLOT(handleUtfsServerStderr())); + connect(utfsServerProc.data(), + SIGNAL(finished(int,QProcess::ExitStatus)), this, + SLOT(handleUtfsServerFinished(int,QProcess::ExitStatus))); + connect(utfsServerProc.data(), SIGNAL(error(QProcess::ProcessError)), + this, SLOT(handleUtfsServerError(QProcess::ProcessError))); + m_startedUtfsServers << utfsServerProc; utfsServerProc->start(utfsServer(), utfsServerArgs); - if (!utfsServerProc->waitForStarted() - || !utfsServerProc->waitForFinished(5000)) { - const QByteArray &errorOutput - = utfsServerProc->readAllStandardError(); - QString errorMsg = tr("Could not start UTFS server: %1") - .arg(utfsServerProc->errorString()); - if (!errorOutput.isEmpty()) { - errorMsg += tr("\nstderr output was: '%1'") - .arg(QString::fromLocal8Bit(errorOutput)); + } +} + +void MaemoRemoteMounter::handleUtfsServerStderr() +{ + if (m_stop) + return; + + for (int i = 0; i < m_startedUtfsServers.count(); ++i) { + UtfsServerInfo &info = m_startedUtfsServers[i]; + if (info.proc.data() == sender()) { + info.output += info.proc->readAllStandardError(); + if (info.output.contains("utfs server is ready")) { + m_readyUtfsServers << info; + m_startedUtfsServers.removeAt(i); + if (m_startedUtfsServers.isEmpty()) { + m_utfsServerTimer->stop(); + emit mounted(); + } + return; + } + break; + } + } + + for (int i = 0; i < m_readyUtfsServers.count(); ++i) { + UtfsServerInfo &info = m_readyUtfsServers[i]; + if (info.proc.data() == sender()) { + const QByteArray &output = info.proc->readAllStandardError(); + qWarning("%s: %s", Q_FUNC_INFO, output.data()); + info.output += output; + } + } +} + +void MaemoRemoteMounter::handleUtfsServerError(QProcess::ProcessError procError) +{ + if (procError != QProcess::FailedToStart) + return; + + for (int i = 0; i < m_startedUtfsServers.count(); ++i) { + const UtfsServerInfo info = m_startedUtfsServers.at(i); + if (info.proc.data() == sender()) { + QString errorString = info.proc->errorString(); + if (!info.output.isEmpty()) { + errorString += tr("\nstderr was: %1") + .arg(QString::fromLocal8Bit(info.output)); } - emit error(errorMsg); + killAllUtfsServers(); + m_utfsServerTimer->stop(); + emit error(tr("Could not start UTFS server: %1").arg(errorString)); return; } - m_utfsServers << utfsServerProc; } - emit mounted(); + qWarning("%s: Process failed to start", Q_FUNC_INFO); +} + +void MaemoRemoteMounter::handleUtfsServerFinished(int exitCode, + QProcess::ExitStatus exitStatus) +{ + if (exitStatus == QProcess::NormalExit && exitCode == 0) + return; + + for (int i = 0; i < m_startedUtfsServers.count(); ++i) { + const UtfsServerInfo info = m_startedUtfsServers.at(i); + if (info.proc.data() == sender()) { + QString errorString = info.proc->errorString(); + if (!info.output.isEmpty()) { + errorString += tr("\nstderr was: %1") + .arg(QString::fromLocal8Bit(info.output)); + } + killAllUtfsServers(); + m_utfsServerTimer->stop(); + emit error(tr("UTFS server finished unexpectedly: %1").arg(errorString)); + return; + } + } } void MaemoRemoteMounter::handleUtfsClientStderr(const QByteArray &output) @@ -327,5 +398,32 @@ QString MaemoRemoteMounter::utfsServer() const return m_toolChain->maddeRoot() + QLatin1String("/madlib/utfs-server"); } +void MaemoRemoteMounter::killAllUtfsServers() +{ + foreach (const UtfsServerInfo &info, m_startedUtfsServers) + killUtfsServer(info.proc.data()); + m_startedUtfsServers.clear(); + foreach (const UtfsServerInfo &info, m_readyUtfsServers) + killUtfsServer(info.proc.data()); + m_readyUtfsServers.clear(); +} + +void MaemoRemoteMounter::killUtfsServer(QProcess *proc) +{ + disconnect(proc, 0, this, 0); + proc->terminate(); + proc->waitForFinished(1000); + proc->kill(); +} + +void MaemoRemoteMounter::handleUtfsServerTimeout() +{ + if (m_stop) + return; + + killAllUtfsServers(); + emit error(tr("Timeout waiting for UTFS servers to connect.")); +} + } // namespace Internal } // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoremotemounter.h b/src/plugins/qt4projectmanager/qt-maemo/maemoremotemounter.h index d7540afe42292771d8634dfa53f8baadc957364a..52a5333e659fa67db1b36118fdfb38756f536740 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemoremotemounter.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemoremotemounter.h @@ -37,10 +37,11 @@ #include <QtCore/QList> #include <QtCore/QObject> +#include <QtCore/QProcess> #include <QtCore/QSharedPointer> #include <QtCore/QString> -QT_FORWARD_DECLARE_CLASS(QProcess); +QT_FORWARD_DECLARE_CLASS(QTimer); namespace Core { class SftpChannel; @@ -61,6 +62,7 @@ public: void setPortList(const MaemoPortList &portList) { m_portList = portList; } bool addMountSpecification(const MaemoMountSpecification &mountSpec, bool mountAsRoot); + void resetMountSpecifications() { m_mountSpecs.clear(); } void mount(); void unmount(); void stop(); @@ -81,16 +83,24 @@ private slots: void handleUtfsClientsFinished(int exitStatus); void handleUnmountProcessFinished(int exitStatus); void handleUtfsClientStderr(const QByteArray &output); + void handleUtfsServerStderr(); + void handleUtfsServerError(QProcess::ProcessError error); + void handleUtfsServerFinished(int exitCode, + QProcess::ExitStatus exitStatus); void handleUmountStderr(const QByteArray &output); + void handleUtfsServerTimeout(); private: void deployUtfsClient(); void startUtfsClients(); void startUtfsServers(); + void killUtfsServer(QProcess *proc); + void killAllUtfsServers(); QString utfsClientOnDevice() const; QString utfsServer() const; const MaemoToolChain * const m_toolChain; + QTimer * const m_utfsServerTimer; struct MountInfo { MountInfo(const MaemoMountSpecification &m, int port, bool root) @@ -108,7 +118,14 @@ private: Core::SftpJobId m_uploadJobId; typedef QSharedPointer<QProcess> ProcPtr; - QList<ProcPtr> m_utfsServers; + struct UtfsServerInfo { + UtfsServerInfo(const ProcPtr &p) : proc(p) {} + ProcPtr proc; + QByteArray output; + }; + QList<UtfsServerInfo> m_startedUtfsServers; + QList<UtfsServerInfo> m_readyUtfsServers; + bool m_stop; QByteArray m_utfsClientStderr; QByteArray m_umountStderr; diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemosshrunner.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemosshrunner.cpp index 4a9d18e18efc4a4e3e9187ba206e5cb4c3e1e300..6e73e25421048e52ef515bc68c125d1874172064 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemosshrunner.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemosshrunner.cpp @@ -187,6 +187,7 @@ void MaemoSshRunner::handleUnmounted() case InitialUnmount: { if (m_stop) return; + m_mounter->resetMountSpecifications(); MaemoPortList portList = m_devConfig.freePorts(); if (m_debugging && !m_runConfig->useRemoteGdb()) portList.getNext(); // One has already been used for gdbserver. @@ -214,6 +215,7 @@ void MaemoSshRunner::handleUnmounted() break; case ShutdownUnmount: Q_ASSERT(m_shuttingDown); + m_mounter->resetMountSpecifications(); m_shuttingDown = false; if (m_exitStatus == SshRemoteProcess::ExitedNormally) { emit remoteProcessFinished(m_runner->exitCode());