From df029015f47f284ced01b8d1f11c4d48cc2f2564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Sat, 22 Jan 2011 15:00:01 +0100 Subject: Close connection properly before quitting. diff --git a/Swiften/Client/ClientSession.cpp b/Swiften/Client/ClientSession.cpp index 9400b56..9950a76 100644 --- a/Swiften/Client/ClientSession.cpp +++ b/Swiften/Client/ClientSession.cpp @@ -62,7 +62,7 @@ ClientSession::~ClientSession() { void ClientSession::start() { stream->onStreamStartReceived.connect(boost::bind(&ClientSession::handleStreamStart, shared_from_this(), _1)); stream->onElementReceived.connect(boost::bind(&ClientSession::handleElement, shared_from_this(), _1)); - stream->onClosed.connect(boost::bind(&ClientSession::handleStreamFinished, shared_from_this(), _1)); + stream->onClosed.connect(boost::bind(&ClientSession::handleStreamClosed, shared_from_this(), _1)); stream->onTLSEncrypted.connect(boost::bind(&ClientSession::handleTLSEncrypted, shared_from_this())); assert(state == Initial); @@ -367,20 +367,10 @@ void ClientSession::continueAfterTLSEncrypted() { sendStreamHeader(); } -void ClientSession::handleStreamFinished(boost::shared_ptr error) { - finishSession(error); -} - -void ClientSession::finish() { - finishSession(boost::shared_ptr()); -} - -void ClientSession::finishSession(Error::Type error) { - finishSession(boost::shared_ptr(new Swift::ClientSession::Error(error))); -} - -void ClientSession::finishSession(boost::shared_ptr error) { +void ClientSession::handleStreamClosed(boost::shared_ptr streamError) { + State previousState = state; state = Finished; + if (stanzaAckRequester_) { stanzaAckRequester_->onRequestAck.disconnect(boost::bind(&ClientSession::requestAck, shared_from_this())); stanzaAckRequester_->onStanzaAcked.disconnect(boost::bind(&ClientSession::handleStanzaAcked, shared_from_this(), _1)); @@ -393,14 +383,32 @@ void ClientSession::finishSession(boost::shared_ptr error) { stream->setWhitespacePingEnabled(false); stream->onStreamStartReceived.disconnect(boost::bind(&ClientSession::handleStreamStart, shared_from_this(), _1)); stream->onElementReceived.disconnect(boost::bind(&ClientSession::handleElement, shared_from_this(), _1)); - stream->onClosed.disconnect(boost::bind(&ClientSession::handleStreamFinished, shared_from_this(), _1)); + stream->onClosed.disconnect(boost::bind(&ClientSession::handleStreamClosed, shared_from_this(), _1)); stream->onTLSEncrypted.disconnect(boost::bind(&ClientSession::handleTLSEncrypted, shared_from_this())); - if (stream->isAvailable()) { - stream->writeFooter(); + + if (previousState == Finishing) { + onFinished(error_); } - onFinished(error); + else { + onFinished(streamError); + } +} + +void ClientSession::finish() { + finishSession(boost::shared_ptr()); } +void ClientSession::finishSession(Error::Type error) { + finishSession(boost::shared_ptr(new Swift::ClientSession::Error(error))); +} + +void ClientSession::finishSession(boost::shared_ptr error) { + state = Finishing; + error_ = error; + assert(stream->isOpen()); + stream->writeFooter(); + stream->close(); +} void ClientSession::requestAck() { stream->writeElement(boost::shared_ptr(new StanzaAckRequest())); diff --git a/Swiften/Client/ClientSession.h b/Swiften/Client/ClientSession.h index f35c298..be0f89e 100644 --- a/Swiften/Client/ClientSession.h +++ b/Swiften/Client/ClientSession.h @@ -37,6 +37,7 @@ namespace Swift { BindingResource, StartingSession, Initialized, + Finishing, Finished }; @@ -115,7 +116,7 @@ namespace Swift { void handleElement(boost::shared_ptr); void handleStreamStart(const ProtocolHeader&); - void handleStreamFinished(boost::shared_ptr); + void handleStreamClosed(boost::shared_ptr); void handleTLSEncrypted(); @@ -139,6 +140,7 @@ namespace Swift { ClientAuthenticator* authenticator; boost::shared_ptr stanzaAckRequester_; boost::shared_ptr stanzaAckResponder_; + boost::shared_ptr error_; CertificateTrustChecker* certificateTrustChecker; }; } diff --git a/Swiften/Client/UnitTest/ClientSessionTest.cpp b/Swiften/Client/UnitTest/ClientSessionTest.cpp index 2b0241a..5d0e2aa 100644 --- a/Swiften/Client/UnitTest/ClientSessionTest.cpp +++ b/Swiften/Client/UnitTest/ClientSessionTest.cpp @@ -296,7 +296,11 @@ class ClientSessionTest : public CppUnit::TestFixture { MockSessionStream() : available(true), canTLSEncrypt(true), tlsEncrypted(false), compressed(false), whitespacePingEnabled(false), resetCount(0) { } - virtual bool isAvailable() { + virtual void close() { + onClosed(boost::shared_ptr()); + } + + virtual bool isOpen() { return available; } diff --git a/Swiften/Component/ComponentSession.cpp b/Swiften/Component/ComponentSession.cpp index 967e68d..c45f663 100644 --- a/Swiften/Component/ComponentSession.cpp +++ b/Swiften/Component/ComponentSession.cpp @@ -24,7 +24,7 @@ ComponentSession::~ComponentSession() { void ComponentSession::start() { stream->onStreamStartReceived.connect(boost::bind(&ComponentSession::handleStreamStart, shared_from_this(), _1)); stream->onElementReceived.connect(boost::bind(&ComponentSession::handleElement, shared_from_this(), _1)); - stream->onClosed.connect(boost::bind(&ComponentSession::handleStreamError, shared_from_this(), _1)); + stream->onClosed.connect(boost::bind(&ComponentSession::handleStreamClosed, shared_from_this(), _1)); assert(state == Initial); state = WaitingForStreamStart; @@ -81,8 +81,19 @@ bool ComponentSession::checkState(State state) { return true; } -void ComponentSession::handleStreamError(boost::shared_ptr error) { - finishSession(error); +void ComponentSession::handleStreamClosed(boost::shared_ptr streamError) { + State oldState = state; + state = Finished; + stream->setWhitespacePingEnabled(false); + stream->onStreamStartReceived.disconnect(boost::bind(&ComponentSession::handleStreamStart, shared_from_this(), _1)); + stream->onElementReceived.disconnect(boost::bind(&ComponentSession::handleElement, shared_from_this(), _1)); + stream->onClosed.disconnect(boost::bind(&ComponentSession::handleStreamClosed, shared_from_this(), _1)); + if (oldState == Finishing) { + onFinished(error); + } + else { + onFinished(streamError); + } } void ComponentSession::finish() { @@ -93,16 +104,12 @@ void ComponentSession::finishSession(Error::Type error) { finishSession(boost::shared_ptr(new Swift::ComponentSession::Error(error))); } -void ComponentSession::finishSession(boost::shared_ptr error) { - state = Finished; - stream->setWhitespacePingEnabled(false); - stream->onStreamStartReceived.disconnect(boost::bind(&ComponentSession::handleStreamStart, shared_from_this(), _1)); - stream->onElementReceived.disconnect(boost::bind(&ComponentSession::handleElement, shared_from_this(), _1)); - stream->onClosed.disconnect(boost::bind(&ComponentSession::handleStreamError, shared_from_this(), _1)); - if (stream->isAvailable()) { - stream->writeFooter(); - } - onFinished(error); +void ComponentSession::finishSession(boost::shared_ptr finishError) { + state = Finishing; + error = finishError; + assert(stream->isOpen()); + stream->writeFooter(); + stream->close(); } } diff --git a/Swiften/Component/ComponentSession.h b/Swiften/Component/ComponentSession.h index cbfa227..dbe6e27 100644 --- a/Swiften/Component/ComponentSession.h +++ b/Swiften/Component/ComponentSession.h @@ -27,6 +27,7 @@ namespace Swift { WaitingForStreamStart, Authenticating, Initialized, + Finishing, Finished }; @@ -68,7 +69,7 @@ namespace Swift { void handleElement(boost::shared_ptr); void handleStreamStart(const ProtocolHeader&); - void handleStreamError(boost::shared_ptr); + void handleStreamClosed(boost::shared_ptr); bool checkState(State); @@ -76,6 +77,7 @@ namespace Swift { JID jid; String secret; boost::shared_ptr stream; + boost::shared_ptr error; State state; }; } diff --git a/Swiften/Component/UnitTest/ComponentSessionTest.cpp b/Swiften/Component/UnitTest/ComponentSessionTest.cpp index 3ad52f9..86776e8 100644 --- a/Swiften/Component/UnitTest/ComponentSessionTest.cpp +++ b/Swiften/Component/UnitTest/ComponentSessionTest.cpp @@ -95,7 +95,11 @@ class ComponentSessionTest : public CppUnit::TestFixture { MockSessionStream() : available(true), whitespacePingEnabled(false), resetCount(0) { } - virtual bool isAvailable() { + virtual void close() { + onClosed(boost::shared_ptr()); + } + + virtual bool isOpen() { return available; } diff --git a/Swiften/Session/BasicSessionStream.cpp b/Swiften/Session/BasicSessionStream.cpp index 5377e6c..03985bd 100644 --- a/Swiften/Session/BasicSessionStream.cpp +++ b/Swiften/Session/BasicSessionStream.cpp @@ -88,7 +88,11 @@ void BasicSessionStream::writeFooter() { xmppLayer->writeFooter(); } -bool BasicSessionStream::isAvailable() { +void BasicSessionStream::close() { + connection->disconnect(); +} + +bool BasicSessionStream::isOpen() { return available; } diff --git a/Swiften/Session/BasicSessionStream.h b/Swiften/Session/BasicSessionStream.h index 330db9d..747177a 100644 --- a/Swiften/Session/BasicSessionStream.h +++ b/Swiften/Session/BasicSessionStream.h @@ -36,7 +36,8 @@ namespace Swift { ); ~BasicSessionStream(); - virtual bool isAvailable(); + virtual void close(); + virtual bool isOpen(); virtual void writeHeader(const ProtocolHeader& header); virtual void writeElement(boost::shared_ptr); diff --git a/Swiften/Session/SessionStream.h b/Swiften/Session/SessionStream.h index 55082f4..d0f93ee 100644 --- a/Swiften/Session/SessionStream.h +++ b/Swiften/Session/SessionStream.h @@ -37,7 +37,8 @@ namespace Swift { virtual ~SessionStream(); - virtual bool isAvailable() = 0; + virtual void close() = 0; + virtual bool isOpen() = 0; virtual void writeHeader(const ProtocolHeader& header) = 0; virtual void writeFooter() = 0; -- cgit v0.10.2-6-g49f6