Maemo: Make states of remote mounter explicit.

Reviewed-by: kh1
This commit is contained in:
Christian Kandeler
2010-10-01 11:49:55 +02:00
parent d856bdf002
commit b4af592dc0
2 changed files with 93 additions and 24 deletions

View File

@@ -35,9 +35,12 @@
#include <coreplugin/ssh/sftpchannel.h> #include <coreplugin/ssh/sftpchannel.h>
#include <coreplugin/ssh/sshconnection.h> #include <coreplugin/ssh/sshconnection.h>
#include <coreplugin/ssh/sshremoteprocess.h> #include <coreplugin/ssh/sshremoteprocess.h>
#include <utils/qtcassert.h>
#include <QtCore/QTimer> #include <QtCore/QTimer>
#define ASSERT_STATE(state) assertState(state, Q_FUNC_INFO)
using namespace Core; using namespace Core;
namespace Qt4ProjectManager { namespace Qt4ProjectManager {
@@ -45,7 +48,7 @@ namespace Internal {
MaemoRemoteMounter::MaemoRemoteMounter(QObject *parent) MaemoRemoteMounter::MaemoRemoteMounter(QObject *parent)
: QObject(parent), m_utfsServerTimer(new QTimer(this)), : QObject(parent), m_utfsServerTimer(new QTimer(this)),
m_uploadJobId(SftpInvalidJob), m_stop(false) m_uploadJobId(SftpInvalidJob), m_state(Inactive)
{ {
connect(m_utfsServerTimer, SIGNAL(timeout()), this, connect(m_utfsServerTimer, SIGNAL(timeout()), this,
SLOT(handleUtfsServerTimeout())); SLOT(handleUtfsServerTimeout()));
@@ -58,12 +61,16 @@ MaemoRemoteMounter::~MaemoRemoteMounter()
void MaemoRemoteMounter::setConnection(const Core::SshConnection::Ptr &connection) void MaemoRemoteMounter::setConnection(const Core::SshConnection::Ptr &connection)
{ {
ASSERT_STATE(Inactive);
m_connection = connection; m_connection = connection;
} }
bool MaemoRemoteMounter::addMountSpecification(const MaemoMountSpecification &mountSpec, bool MaemoRemoteMounter::addMountSpecification(const MaemoMountSpecification &mountSpec,
bool mountAsRoot) bool mountAsRoot)
{ {
ASSERT_STATE(Inactive);
if (mountSpec.isValid()) { if (mountSpec.isValid()) {
if (!m_portList.hasMore()) if (!m_portList.hasMore())
return false; return false;
@@ -75,21 +82,27 @@ bool MaemoRemoteMounter::addMountSpecification(const MaemoMountSpecification &mo
void MaemoRemoteMounter::mount() void MaemoRemoteMounter::mount()
{ {
m_stop = false; ASSERT_STATE(Inactive);
Q_ASSERT(m_utfsServers.isEmpty()); Q_ASSERT(m_utfsServers.isEmpty());
Q_ASSERT(m_connection);
if (!m_toolChain->allowsRemoteMounts()) if (!m_toolChain->allowsRemoteMounts())
m_mountSpecs.clear(); m_mountSpecs.clear();
if (m_mountSpecs.isEmpty()) if (m_mountSpecs.isEmpty()) {
m_state = Inactive;
emit reportProgress(tr("No directories to mount"));
emit mounted(); emit mounted();
else } else {
deployUtfsClient(); deployUtfsClient();
}
} }
void MaemoRemoteMounter::unmount() void MaemoRemoteMounter::unmount()
{ {
m_stop = false; ASSERT_STATE(Inactive);
if (m_mountSpecs.isEmpty()) { if (m_mountSpecs.isEmpty()) {
emit reportProgress(tr("No directories to unmount"));
emit unmounted(); emit unmounted();
return; return;
} }
@@ -108,13 +121,17 @@ void MaemoRemoteMounter::unmount()
SLOT(handleUnmountProcessFinished(int))); SLOT(handleUnmountProcessFinished(int)));
connect(m_unmountProcess.data(), SIGNAL(errorOutputAvailable(QByteArray)), connect(m_unmountProcess.data(), SIGNAL(errorOutputAvailable(QByteArray)),
this, SLOT(handleUmountStderr(QByteArray))); this, SLOT(handleUmountStderr(QByteArray)));
m_state = Unmounting;
m_unmountProcess->start(); m_unmountProcess->start();
} }
void MaemoRemoteMounter::handleUnmountProcessFinished(int exitStatus) void MaemoRemoteMounter::handleUnmountProcessFinished(int exitStatus)
{ {
if (m_stop) ASSERT_STATE(QList<State>() << Unmounting << Inactive);
if (m_state == Inactive)
return; return;
m_state = Inactive;
QString errorMsg; QString errorMsg;
switch (exitStatus) { switch (exitStatus) {
@@ -148,7 +165,7 @@ void MaemoRemoteMounter::handleUnmountProcessFinished(int exitStatus)
void MaemoRemoteMounter::stop() void MaemoRemoteMounter::stop()
{ {
m_stop = true; m_state = Inactive;
if (m_utfsClientUploader) { if (m_utfsClientUploader) {
disconnect(m_utfsClientUploader.data(), 0, this, 0); disconnect(m_utfsClientUploader.data(), 0, this, 0);
m_utfsClientUploader->closeChannel(); m_utfsClientUploader->closeChannel();
@@ -172,19 +189,24 @@ void MaemoRemoteMounter::deployUtfsClient()
connect(m_utfsClientUploader.data(), SIGNAL(initializationFailed(QString)), connect(m_utfsClientUploader.data(), SIGNAL(initializationFailed(QString)),
this, SLOT(handleUploaderInitializationFailed(QString))); this, SLOT(handleUploaderInitializationFailed(QString)));
m_utfsClientUploader->initialize(); m_utfsClientUploader->initialize();
m_state = UploaderInitializing;
} }
void MaemoRemoteMounter::handleUploaderInitializationFailed(const QString &reason) void MaemoRemoteMounter::handleUploaderInitializationFailed(const QString &reason)
{ {
if (m_stop) ASSERT_STATE(QList<State>() << UploaderInitializing << Inactive);
return;
emit error(tr("Failed to establish SFTP connection: %1").arg(reason)); if (m_state == UploaderInitializing) {
emit error(tr("Failed to establish SFTP connection: %1").arg(reason));
m_state = Inactive;
}
} }
void MaemoRemoteMounter::handleUploaderInitialized() void MaemoRemoteMounter::handleUploaderInitialized()
{ {
if (m_stop) ASSERT_STATE(QList<State>() << UploaderInitializing << Inactive);
if (m_state == Inactive)
return; return;
emit reportProgress(tr("Uploading UTFS client...")); emit reportProgress(tr("Uploading UTFS client..."));
@@ -195,14 +217,20 @@ void MaemoRemoteMounter::handleUploaderInitialized()
= m_toolChain->maddeRoot() + QLatin1String("/madlib/armel/utfs-client"); = m_toolChain->maddeRoot() + QLatin1String("/madlib/armel/utfs-client");
m_uploadJobId = m_utfsClientUploader->uploadFile(localFile, m_uploadJobId = m_utfsClientUploader->uploadFile(localFile,
utfsClientOnDevice(), SftpOverwriteExisting); utfsClientOnDevice(), SftpOverwriteExisting);
if (m_uploadJobId == SftpInvalidJob) if (m_uploadJobId == SftpInvalidJob) {
m_state = Inactive;
emit error(tr("Could not upload UTFS client (%1).").arg(localFile)); emit error(tr("Could not upload UTFS client (%1).").arg(localFile));
}
m_state = UploadRunning;
} }
void MaemoRemoteMounter::handleUploadFinished(Core::SftpJobId jobId, void MaemoRemoteMounter::handleUploadFinished(Core::SftpJobId jobId,
const QString &errorMsg) const QString &errorMsg)
{ {
if (m_stop) ASSERT_STATE(QList<State>() << UploadRunning << Inactive);
if (m_state == Inactive)
return; return;
if (jobId != m_uploadJobId) { if (jobId != m_uploadJobId) {
@@ -213,6 +241,7 @@ void MaemoRemoteMounter::handleUploadFinished(Core::SftpJobId jobId,
m_uploadJobId = SftpInvalidJob; m_uploadJobId = SftpInvalidJob;
if (!errorMsg.isEmpty()) { if (!errorMsg.isEmpty()) {
emit error(tr("Could not upload UTFS client: %1").arg(errorMsg)); emit error(tr("Could not upload UTFS client: %1").arg(errorMsg));
m_state = Inactive;
return; return;
} }
@@ -255,22 +284,32 @@ void MaemoRemoteMounter::startUtfsClients()
connect(m_mountProcess.data(), SIGNAL(errorOutputAvailable(QByteArray)), connect(m_mountProcess.data(), SIGNAL(errorOutputAvailable(QByteArray)),
this, SLOT(handleUtfsClientStderr(QByteArray))); this, SLOT(handleUtfsClientStderr(QByteArray)));
m_mountProcess->start(); m_mountProcess->start();
m_state = UtfsClientsStarting;
} }
void MaemoRemoteMounter::handleUtfsClientsStarted() void MaemoRemoteMounter::handleUtfsClientsStarted()
{ {
if (!m_stop) ASSERT_STATE(QList<State>() << UtfsClientsStarting << Inactive);
if (m_state == UtfsClientsStarting) {
m_state = UtfsClientsStarted;
QTimer::singleShot(250, this, SLOT(startUtfsServers())); QTimer::singleShot(250, this, SLOT(startUtfsServers()));
}
} }
void MaemoRemoteMounter::handleUtfsClientsFinished(int exitStatus) void MaemoRemoteMounter::handleUtfsClientsFinished(int exitStatus)
{ {
if (m_stop) ASSERT_STATE(QList<State>() << UtfsClientsStarting << UtfsClientsStarted
<< UtfsServersStarted << Inactive);
if (m_state == Inactive)
return; return;
m_state = Inactive;
if (exitStatus == SshRemoteProcess::ExitedNormally if (exitStatus == SshRemoteProcess::ExitedNormally
&& m_mountProcess->exitCode() == 0) { && m_mountProcess->exitCode() == 0) {
m_utfsServerTimer->stop(); m_utfsServerTimer->stop();
emit reportProgress(tr("Mount operation succeeded."));
emit mounted(); emit mounted();
} else { } else {
QString errMsg = tr("Failure running UTFS client: %1") QString errMsg = tr("Failure running UTFS client: %1")
@@ -284,7 +323,9 @@ void MaemoRemoteMounter::handleUtfsClientsFinished(int exitStatus)
void MaemoRemoteMounter::startUtfsServers() void MaemoRemoteMounter::startUtfsServers()
{ {
if (m_stop) ASSERT_STATE(QList<State>() << UtfsClientsStarted << Inactive);
if (m_state == Inactive)
return; return;
emit reportProgress(tr("Starting UTFS servers...")); emit reportProgress(tr("Starting UTFS servers..."));
@@ -310,11 +351,13 @@ void MaemoRemoteMounter::startUtfsServers()
m_utfsServers << utfsServerProc; m_utfsServers << utfsServerProc;
utfsServerProc->start(utfsServer(), utfsServerArgs); utfsServerProc->start(utfsServer(), utfsServerArgs);
} }
m_state = UtfsServersStarted;
} }
void MaemoRemoteMounter::handleUtfsServerStderr() void MaemoRemoteMounter::handleUtfsServerStderr()
{ {
if (!m_stop) { if (m_state != Inactive) {
QProcess * const proc = static_cast<QProcess *>(sender()); QProcess * const proc = static_cast<QProcess *>(sender());
const QByteArray &output = proc->readAllStandardError(); const QByteArray &output = proc->readAllStandardError();
emit debugOutput(QString::fromLocal8Bit(output)); emit debugOutput(QString::fromLocal8Bit(output));
@@ -323,7 +366,7 @@ void MaemoRemoteMounter::handleUtfsServerStderr()
void MaemoRemoteMounter::handleUtfsServerError(QProcess::ProcessError) void MaemoRemoteMounter::handleUtfsServerError(QProcess::ProcessError)
{ {
if (m_stop || m_utfsServers.isEmpty()) if (m_state == Inactive || m_utfsServers.isEmpty())
return; return;
QProcess * const proc = static_cast<QProcess *>(sender()); QProcess * const proc = static_cast<QProcess *>(sender());
@@ -336,23 +379,27 @@ void MaemoRemoteMounter::handleUtfsServerError(QProcess::ProcessError)
killAllUtfsServers(); killAllUtfsServers();
m_utfsServerTimer->stop(); m_utfsServerTimer->stop();
emit error(tr("Error running UTFS server: %1").arg(errorString)); emit error(tr("Error running UTFS server: %1").arg(errorString));
m_state = Inactive;
} }
void MaemoRemoteMounter::handleUtfsServerFinished(int /* exitCode */, void MaemoRemoteMounter::handleUtfsServerFinished(int /* exitCode */,
QProcess::ExitStatus exitStatus) QProcess::ExitStatus exitStatus)
{ {
if (!m_stop && exitStatus != QProcess::NormalExit) if (m_state != Inactive && exitStatus != QProcess::NormalExit)
handleUtfsServerError(static_cast<QProcess *>(sender())->error()); handleUtfsServerError(static_cast<QProcess *>(sender())->error());
} }
void MaemoRemoteMounter::handleUtfsClientStderr(const QByteArray &output) void MaemoRemoteMounter::handleUtfsClientStderr(const QByteArray &output)
{ {
m_utfsClientStderr += output; if (m_state != Inactive)
m_utfsClientStderr += output;
} }
void MaemoRemoteMounter::handleUmountStderr(const QByteArray &output) void MaemoRemoteMounter::handleUmountStderr(const QByteArray &output)
{ {
m_umountStderr += output; if (m_state != Inactive)
m_umountStderr += output;
} }
QString MaemoRemoteMounter::utfsClientOnDevice() const QString MaemoRemoteMounter::utfsClientOnDevice() const
@@ -383,11 +430,26 @@ void MaemoRemoteMounter::killUtfsServer(QProcess *proc)
void MaemoRemoteMounter::handleUtfsServerTimeout() void MaemoRemoteMounter::handleUtfsServerTimeout()
{ {
if (m_stop) ASSERT_STATE(QList<State>() << UtfsServersStarted << Inactive);
if (m_state == Inactive)
return; return;
killAllUtfsServers(); killAllUtfsServers();
emit error(tr("Timeout waiting for UTFS servers to connect.")); emit error(tr("Timeout waiting for UTFS servers to connect."));
m_state = Inactive;
}
void MaemoRemoteMounter::assertState(State expectedState, const char *func)
{
assertState(QList<State>() << expectedState, func);
}
void MaemoRemoteMounter::assertState(const QList<State> &expectedStates,
const char *func)
{
QTC_ASSERT(expectedStates.contains(m_state),
qDebug("Unexpected state %d at %s.", m_state, func))
} }
} // namespace Internal } // namespace Internal

View File

@@ -75,7 +75,7 @@ signals:
void mounted(); void mounted();
void unmounted(); void unmounted();
void error(const QString &reason); void error(const QString &reason);
void reportProgress(const QString &progressOutput); void reportProgress(const QString &progressOutput); // TODO: No progress output when there's nothingt to mount
void debugOutput(const QString &output); void debugOutput(const QString &output);
private slots: private slots:
@@ -123,10 +123,17 @@ private:
typedef QSharedPointer<QProcess> ProcPtr; typedef QSharedPointer<QProcess> ProcPtr;
QList<ProcPtr> m_utfsServers; QList<ProcPtr> m_utfsServers;
bool m_stop;
QByteArray m_utfsClientStderr; QByteArray m_utfsClientStderr;
QByteArray m_umountStderr; QByteArray m_umountStderr;
MaemoPortList m_portList; MaemoPortList m_portList;
enum State {
Inactive, Unmounting, UploaderInitializing, UploadRunning,
UtfsClientsStarting, UtfsClientsStarted, UtfsServersStarted
};
void assertState(State expectedState, const char *func);
void assertState(const QList<State> &expectedStates, const char *func);
State m_state;
}; };
} // namespace Internal } // namespace Internal