summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2010-12-27 15:10:27 (GMT)
committerRemko Tronçon <git@el-tramo.be>2010-12-27 15:24:23 (GMT)
commit2ef4bb560dad95555a5ae94d0bd5bff49d50d3d3 (patch)
tree79a7eceecc4afe8785323983a1e4496dd52d7dd8
parentcd9c5b8d87aaae48a058ae8d498bc81d0fed82ad (diff)
downloadswift-contrib-2ef4bb560dad95555a5ae94d0bd5bff49d50d3d3.zip
swift-contrib-2ef4bb560dad95555a5ae94d0bd5bff49d50d3d3.tar.bz2
Avoid leaking connection on exit.
-rw-r--r--QA/valgrind.supp7
-rw-r--r--Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp1
-rw-r--r--Swiften/Client/ClientSession.h4
-rw-r--r--Swiften/Client/CoreClient.cpp8
-rw-r--r--Swiften/Component/CoreComponent.cpp1
-rw-r--r--Swiften/Session/BasicSessionStream.cpp39
-rw-r--r--Swiften/Session/BasicSessionStream.h7
-rw-r--r--Swiften/StreamStack/ConnectionLayer.h4
8 files changed, 43 insertions, 28 deletions
diff --git a/QA/valgrind.supp b/QA/valgrind.supp
index 8601b60..fe09cef 100644
--- a/QA/valgrind.supp
+++ b/QA/valgrind.supp
@@ -90,3 +90,10 @@
Memcheck:Cond
fun:*mersenne_twister*
}
+
+{
+ <insert_a_suppression_name_here>
+ Memcheck:Leak
+ fun:malloc
+ fun:__cxa_get_globals
+}
diff --git a/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp b/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp
index 00fc11d..5d7961b 100644
--- a/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp
+++ b/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp
@@ -38,6 +38,7 @@ public:
void tearDown() {
delete notifier_;
+ delete entityCapsProvider;
delete stanzaChannel;
}
diff --git a/Swiften/Client/ClientSession.h b/Swiften/Client/ClientSession.h
index 170491f..b779735 100644
--- a/Swiften/Client/ClientSession.h
+++ b/Swiften/Client/ClientSession.h
@@ -81,6 +81,10 @@ namespace Swift {
void start();
void finish();
+ bool isFinished() const {
+ return getState() == Finished;
+ }
+
void sendCredentials(const String& password);
void sendStanza(boost::shared_ptr<Stanza>);
diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp
index 7b1f3fd..46b4cbb 100644
--- a/Swiften/Client/CoreClient.cpp
+++ b/Swiften/Client/CoreClient.cpp
@@ -34,7 +34,7 @@ CoreClient::CoreClient(EventLoop* eventLoop, NetworkFactories* networkFactories,
}
CoreClient::~CoreClient() {
- if (session_ || connection_) {
+ if ((session_ && !session_->isFinished()) || connection_) {
std::cerr << "Warning: Client not disconnected properly" << std::endl;
}
delete tlsFactories;
@@ -79,7 +79,6 @@ void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connectio
}
sessionStream_->onDataRead.connect(boost::bind(&CoreClient::handleDataRead, this, _1));
sessionStream_->onDataWritten.connect(boost::bind(&CoreClient::handleDataWritten, this, _1));
- sessionStream_->initialize();
session_ = ClientSession::create(jid_, sessionStream_);
session_->setCertificateTrustChecker(certificateTrustChecker);
@@ -94,7 +93,7 @@ void CoreClient::disconnect() {
// FIXME: We should be able to do without this boolean. We just have to make sure we can tell the difference between
// connector finishing without a connection due to an error or because of a disconnect.
disconnectRequested_ = true;
- if (session_) {
+ if (!session_->isFinished()) {
session_->finish();
}
else if (connector_) {
@@ -109,7 +108,6 @@ void CoreClient::setCertificate(const String& certificate) {
void CoreClient::handleSessionFinished(boost::shared_ptr<Error> error) {
session_->onFinished.disconnect(boost::bind(&CoreClient::handleSessionFinished, this, _1));
session_->onNeedCredentials.disconnect(boost::bind(&CoreClient::handleNeedCredentials, this));
- session_.reset();
sessionStream_->onDataRead.disconnect(boost::bind(&CoreClient::handleDataRead, this, _1));
sessionStream_->onDataWritten.disconnect(boost::bind(&CoreClient::handleDataWritten, this, _1));
@@ -244,7 +242,7 @@ void CoreClient::sendPresence(boost::shared_ptr<Presence> presence) {
}
bool CoreClient::isActive() const {
- return session_ || connector_;
+ return (session_ && !session_->isFinished()) || connector_;
}
void CoreClient::setCertificateTrustChecker(CertificateTrustChecker* checker) {
diff --git a/Swiften/Component/CoreComponent.cpp b/Swiften/Component/CoreComponent.cpp
index c3451de..eabe62d 100644
--- a/Swiften/Component/CoreComponent.cpp
+++ b/Swiften/Component/CoreComponent.cpp
@@ -65,7 +65,6 @@ void CoreComponent::handleConnectorFinished(boost::shared_ptr<Connection> connec
sessionStream_ = boost::shared_ptr<BasicSessionStream>(new BasicSessionStream(ComponentStreamType, connection_, getPayloadParserFactories(), getPayloadSerializers(), NULL, networkFactories->getTimerFactory()));
sessionStream_->onDataRead.connect(boost::bind(&CoreComponent::handleDataRead, this, _1));
sessionStream_->onDataWritten.connect(boost::bind(&CoreComponent::handleDataWritten, this, _1));
- sessionStream_->initialize();
session_ = ComponentSession::create(jid_, secret_, sessionStream_);
stanzaChannel_->setSession(session_);
diff --git a/Swiften/Session/BasicSessionStream.cpp b/Swiften/Session/BasicSessionStream.cpp
index c4d1b6d..3f06315 100644
--- a/Swiften/Session/BasicSessionStream.cpp
+++ b/Swiften/Session/BasicSessionStream.cpp
@@ -33,23 +33,17 @@ BasicSessionStream::BasicSessionStream(
tlsContextFactory(tlsContextFactory),
timerFactory(timerFactory),
streamType(streamType),
- xmppLayer(NULL),
- connectionLayer(NULL),
compressionLayer(NULL),
tlsLayer(NULL),
whitespacePingLayer(NULL) {
-}
-
-void BasicSessionStream::initialize() {
xmppLayer = new XMPPLayer(payloadParserFactories, payloadSerializers, streamType);
- xmppLayer->onStreamStart.connect(boost::bind(&BasicSessionStream::handleStreamStartReceived, shared_from_this(), _1));
- xmppLayer->onElement.connect(boost::bind(&BasicSessionStream::handleElementReceived, shared_from_this(), _1));
- xmppLayer->onError.connect(boost::bind(
- &BasicSessionStream::handleXMPPError, shared_from_this()));
- xmppLayer->onDataRead.connect(boost::bind(&BasicSessionStream::handleDataRead, shared_from_this(), _1));
- xmppLayer->onWriteData.connect(boost::bind(&BasicSessionStream::handleDataWritten, shared_from_this(), _1));
-
- connection->onDisconnected.connect(boost::bind(&BasicSessionStream::handleConnectionError, shared_from_this(), _1));
+ xmppLayer->onStreamStart.connect(boost::bind(&BasicSessionStream::handleStreamStartReceived, this, _1));
+ xmppLayer->onElement.connect(boost::bind(&BasicSessionStream::handleElementReceived, this, _1));
+ xmppLayer->onError.connect(boost::bind(&BasicSessionStream::handleXMPPError, this));
+ xmppLayer->onDataRead.connect(boost::bind(&BasicSessionStream::handleDataRead, this, _1));
+ xmppLayer->onWriteData.connect(boost::bind(&BasicSessionStream::handleDataWritten, this, _1));
+
+ connection->onDisconnected.connect(boost::bind(&BasicSessionStream::handleConnectionError, this, _1));
connectionLayer = new ConnectionLayer(connection);
streamStack = new StreamStack(xmppLayer, connectionLayer);
@@ -59,10 +53,23 @@ void BasicSessionStream::initialize() {
BasicSessionStream::~BasicSessionStream() {
delete compressionLayer;
- delete tlsLayer;
+
+ if (tlsLayer) {
+ tlsLayer->onError.disconnect(boost::bind(&BasicSessionStream::handleTLSError, this));
+ tlsLayer->onConnected.disconnect(boost::bind(&BasicSessionStream::handleTLSConnected, this));
+ delete tlsLayer;
+ }
delete whitespacePingLayer;
delete streamStack;
+
+ connection->onDisconnected.disconnect(boost::bind(&BasicSessionStream::handleConnectionError, this, _1));
delete connectionLayer;
+
+ xmppLayer->onStreamStart.disconnect(boost::bind(&BasicSessionStream::handleStreamStartReceived, this, _1));
+ xmppLayer->onElement.disconnect(boost::bind(&BasicSessionStream::handleElementReceived, this, _1));
+ xmppLayer->onError.disconnect(boost::bind(&BasicSessionStream::handleXMPPError, this));
+ xmppLayer->onDataRead.disconnect(boost::bind(&BasicSessionStream::handleDataRead, this, _1));
+ xmppLayer->onWriteData.disconnect(boost::bind(&BasicSessionStream::handleDataWritten, this, _1));
delete xmppLayer;
}
@@ -97,8 +104,8 @@ void BasicSessionStream::addTLSEncryption() {
}
else {
streamStack->addLayer(tlsLayer);
- tlsLayer->onError.connect(boost::bind(&BasicSessionStream::handleTLSError, shared_from_this()));
- tlsLayer->onConnected.connect(boost::bind(&BasicSessionStream::handleTLSConnected, shared_from_this()));
+ tlsLayer->onError.connect(boost::bind(&BasicSessionStream::handleTLSError, this));
+ tlsLayer->onConnected.connect(boost::bind(&BasicSessionStream::handleTLSConnected, this));
tlsLayer->connect();
}
}
diff --git a/Swiften/Session/BasicSessionStream.h b/Swiften/Session/BasicSessionStream.h
index c601792..35b5481 100644
--- a/Swiften/Session/BasicSessionStream.h
+++ b/Swiften/Session/BasicSessionStream.h
@@ -7,7 +7,6 @@
#pragma once
#include <boost/shared_ptr.hpp>
-#include <boost/enable_shared_from_this.hpp>
#include "Swiften/Network/Connection.h"
#include "Swiften/Session/SessionStream.h"
@@ -25,9 +24,7 @@ namespace Swift {
class ConnectionLayer;
class CompressionLayer;
- class BasicSessionStream :
- public SessionStream,
- public boost::enable_shared_from_this<BasicSessionStream> {
+ class BasicSessionStream : public SessionStream {
public:
BasicSessionStream(
StreamType streamType,
@@ -39,8 +36,6 @@ namespace Swift {
);
~BasicSessionStream();
- void initialize();
-
virtual bool isAvailable();
virtual void writeHeader(const ProtocolHeader& header);
diff --git a/Swiften/StreamStack/ConnectionLayer.h b/Swiften/StreamStack/ConnectionLayer.h
index fab014e..0da0900 100644
--- a/Swiften/StreamStack/ConnectionLayer.h
+++ b/Swiften/StreamStack/ConnectionLayer.h
@@ -20,6 +20,10 @@ namespace Swift {
connection->onDataRead.connect(boost::bind(&ConnectionLayer::writeDataToParentLayer, this, _1));
}
+ ~ConnectionLayer() {
+ connection->onDataRead.disconnect(boost::bind(&ConnectionLayer::writeDataToParentLayer, this, _1));
+ }
+
void writeData(const ByteArray& data) {
connection->write(data);
}