From 3c10fc18a1b48a6a0a3c03e1bd8901c2a3526a17 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 16 Aug 2010 22:10:34 +0200 Subject: [PATCH] SSH: Prepare infrastructure for more timeout handling. --- src/plugins/coreplugin/ssh/sshchannel_p.h | 7 ++++++- src/plugins/coreplugin/ssh/sshchannelmanager.cpp | 8 ++++---- src/plugins/coreplugin/ssh/sshchannelmanager_p.h | 10 +++++++--- src/plugins/coreplugin/ssh/sshconnection.cpp | 12 +++++++----- src/plugins/coreplugin/ssh/sshconnection_p.h | 2 +- 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/plugins/coreplugin/ssh/sshchannel_p.h b/src/plugins/coreplugin/ssh/sshchannel_p.h index 993357d8713..ce86bf3651f 100644 --- a/src/plugins/coreplugin/ssh/sshchannel_p.h +++ b/src/plugins/coreplugin/ssh/sshchannel_p.h @@ -31,6 +31,7 @@ #define SSHCHANNEL_P_H #include +#include #include namespace Core { @@ -39,8 +40,9 @@ namespace Internal { class SshIncomingPacket; class SshSendFacility; -class AbstractSshChannel +class AbstractSshChannel : public QObject { + Q_OBJECT public: enum ChannelState { Inactive, SessionRequested, SessionEstablished, CloseRequested, Closed @@ -76,6 +78,9 @@ public: virtual ~AbstractSshChannel(); +signals: + void timeout(); + protected: AbstractSshChannel(quint32 channelId, SshSendFacility &sendFacility); diff --git a/src/plugins/coreplugin/ssh/sshchannelmanager.cpp b/src/plugins/coreplugin/ssh/sshchannelmanager.cpp index c7d31136971..f1e0060dc14 100644 --- a/src/plugins/coreplugin/ssh/sshchannelmanager.cpp +++ b/src/plugins/coreplugin/ssh/sshchannelmanager.cpp @@ -41,13 +41,12 @@ namespace Core { namespace Internal { -SshChannelManager::SshChannelManager(SshSendFacility &sendFacility) - : m_sendFacility(sendFacility), m_nextLocalChannelId(0) +SshChannelManager::SshChannelManager(SshSendFacility &sendFacility, + QObject *parent) + : QObject(parent), m_sendFacility(sendFacility), m_nextLocalChannelId(0) { } -SshChannelManager::~SshChannelManager() {} - void SshChannelManager::handleChannelRequest(const SshIncomingPacket &packet) { lookupChannel(packet.extractRecipientChannel()) @@ -164,6 +163,7 @@ Core::SftpChannel::Ptr SshChannelManager::createSftpChannel() void SshChannelManager::insertChannel(AbstractSshChannel *priv, const QSharedPointer &pub) { + connect(priv, SIGNAL(timeout()), this, SIGNAL(timeout())); m_channels.insert(priv->localChannelId(), priv); m_sessions.insert(priv, pub); } diff --git a/src/plugins/coreplugin/ssh/sshchannelmanager_p.h b/src/plugins/coreplugin/ssh/sshchannelmanager_p.h index fe62c009241..adcc924ebaf 100644 --- a/src/plugins/coreplugin/ssh/sshchannelmanager_p.h +++ b/src/plugins/coreplugin/ssh/sshchannelmanager_p.h @@ -31,6 +31,7 @@ #define SSHCHANNELLAYER_P_H #include +#include #include namespace Core { @@ -44,11 +45,11 @@ class AbstractSshChannel; class SshIncomingPacket; class SshSendFacility; -class SshChannelManager +class SshChannelManager : public QObject { + Q_OBJECT public: - SshChannelManager(SshSendFacility &sendFacility); - ~SshChannelManager(); + SshChannelManager(SshSendFacility &sendFacility, QObject *parent); QSharedPointer createRemoteProcess(const QByteArray &command); QSharedPointer createSftpChannel(); @@ -66,6 +67,9 @@ public: void handleChannelEof(const SshIncomingPacket &packet); void handleChannelClose(const SshIncomingPacket &packet); +signals: + void timeout(); + private: typedef QHash::Iterator ChannelIterator; diff --git a/src/plugins/coreplugin/ssh/sshconnection.cpp b/src/plugins/coreplugin/ssh/sshconnection.cpp index f975b031c6b..1746785a61c 100644 --- a/src/plugins/coreplugin/ssh/sshconnection.cpp +++ b/src/plugins/coreplugin/ssh/sshconnection.cpp @@ -149,11 +149,12 @@ namespace Internal { SshConnectionPrivate::SshConnectionPrivate(SshConnection *conn) : m_socket(new QTcpSocket(this)), m_state(SocketUnconnected), m_sendFacility(m_socket), - m_channelManager(new SshChannelManager(m_sendFacility)), + m_channelManager(new SshChannelManager(m_sendFacility, this)), m_error(SshNoError), m_ignoreNextPacket(false), m_conn(conn) { setupPacketHandlers(); - connect(&m_timeoutTimer, SIGNAL(timeout()), this, SLOT(handleTimeout())); + m_timeoutTimer.setSingleShot(true); + connect(m_channelManager, SIGNAL(timeout()), this, SLOT(handleTimeout())); } SshConnectionPrivate::~SshConnectionPrivate() @@ -501,9 +502,8 @@ void SshConnectionPrivate::handleSocketError() void SshConnectionPrivate::handleTimeout() { - if (m_state != ConnectionEstablished) - closeConnection(SSH_DISCONNECT_BY_APPLICATION, SshTimeoutError, "", - tr("Connection timed out.")); + closeConnection(SSH_DISCONNECT_BY_APPLICATION, SshTimeoutError, "", + tr("Timeout waiting for reply from server.")); } void SshConnectionPrivate::connectToHost(const SshConnectionParameters &serverInfo) @@ -520,6 +520,7 @@ void SshConnectionPrivate::connectToHost(const SshConnectionParameters &serverIn SLOT(handleSocketError())); connect(m_socket, SIGNAL(disconnected()), this, SLOT(handleSocketDisconnected())); + connect(&m_timeoutTimer, SIGNAL(timeout()), this, SLOT(handleTimeout())); this->m_connParams = serverInfo; m_state = SocketConnecting; m_timeoutTimer.start(m_connParams.timeout * 1000); @@ -538,6 +539,7 @@ void SshConnectionPrivate::closeConnection(SshErrorCode sshError, m_errorString = userErrorString; m_timeoutTimer.stop(); disconnect(m_socket, 0, this, 0); + disconnect(&m_timeoutTimer, 0, this, 0); try { m_channelManager->closeAllChannels(); m_sendFacility.sendDisconnectPacket(sshError, serverErrorString); diff --git a/src/plugins/coreplugin/ssh/sshconnection_p.h b/src/plugins/coreplugin/ssh/sshconnection_p.h index cd9e3d771cd..2dd3c5c3352 100644 --- a/src/plugins/coreplugin/ssh/sshconnection_p.h +++ b/src/plugins/coreplugin/ssh/sshconnection_p.h @@ -141,7 +141,7 @@ private: SshStateInternal m_state; SshIncomingPacket m_incomingPacket; SshSendFacility m_sendFacility; - QScopedPointer m_channelManager; + SshChannelManager * const m_channelManager; SshConnectionParameters m_connParams; QByteArray m_incomingData; SshError m_error;