From f061668e3c1d5eac01b85303e2c81df2bc560e9a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Wed, 15 Jul 2009 20:07:44 +0200
Subject: Make stream stack layers reference counted.


diff --git a/Limber/main.cpp b/Limber/main.cpp
index 200f2e4..5d1bb6a 100644
--- a/Limber/main.cpp
+++ b/Limber/main.cpp
@@ -3,6 +3,7 @@
 #include <boost/asio.hpp>
 #include <boost/bind.hpp>
 #include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
 
 #include "Swiften/Elements/IQ.h"
 #include "Swiften/Elements/RosterPayload.h"
@@ -12,6 +13,7 @@
 #include "Swiften/Base/IDGenerator.h"
 #include "Swiften/EventLoop/MainEventLoop.h"
 #include "Swiften/EventLoop/SimpleEventLoop.h"
+#include "Swiften/EventLoop/EventOwner.h"
 #include "Swiften/Elements/Stanza.h"
 #include "Swiften/Network/ConnectionServer.h"
 #include "Swiften/Network/BoostConnection.h"
@@ -22,9 +24,12 @@
 
 using namespace Swift;
 
-class BoostConnectionServer : public ConnectionServer {
+class BoostConnectionServer : public ConnectionServer, public EventOwner, public boost::enable_shared_from_this<BoostConnectionServer> {
 	public:
 		BoostConnectionServer(int port, boost::asio::io_service& ioService) : acceptor_(ioService, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)) {
+		}
+
+		void start() {
 			acceptNextConnection();
 		}
 
@@ -32,12 +37,12 @@ class BoostConnectionServer : public ConnectionServer {
 		void acceptNextConnection() {
 			boost::shared_ptr<BoostConnection> newConnection(new BoostConnection(&acceptor_.io_service()));
 			acceptor_.async_accept(newConnection->getSocket(), 
-				boost::bind(&BoostConnectionServer::handleAccept, this, newConnection, boost::asio::placeholders::error));
+				boost::bind(&BoostConnectionServer::handleAccept, shared_from_this(), newConnection, boost::asio::placeholders::error));
 		}
 
 		void handleAccept(boost::shared_ptr<BoostConnection> newConnection, const boost::system::error_code& error) {
 			if (!error) {
-				MainEventLoop::postEvent(boost::bind(boost::ref(onNewConnection), newConnection), this);
+				MainEventLoop::postEvent(boost::bind(boost::ref(onNewConnection), newConnection), shared_from_this());
 				newConnection->listen();
 				acceptNextConnection();
 			}
@@ -49,12 +54,9 @@ class BoostConnectionServer : public ConnectionServer {
 class Server {
 	public:
 		Server(UserRegistry* userRegistry) : userRegistry_(userRegistry) {
-			serverFromClientConnectionServer_ = new BoostConnectionServer(5222, boostIOServiceThread_.getIOService());
+			serverFromClientConnectionServer_ = boost::shared_ptr<BoostConnectionServer>(new BoostConnectionServer(5224, boostIOServiceThread_.getIOService()));
 			serverFromClientConnectionServer_->onNewConnection.connect(boost::bind(&Server::handleNewConnection, this, _1));
-		}
-
-		~Server() {
-			delete serverFromClientConnectionServer_;
+			serverFromClientConnectionServer_->start();
 		}
 
 	private:
@@ -101,7 +103,7 @@ class Server {
 		IDGenerator idGenerator_;
 		UserRegistry* userRegistry_;
 		BoostIOServiceThread boostIOServiceThread_;
-		BoostConnectionServer* serverFromClientConnectionServer_;
+		boost::shared_ptr<BoostConnectionServer> serverFromClientConnectionServer_;
 		std::vector<ServerFromClientSession*> serverFromClientSessions_;
 		FullPayloadParserFactoryCollection payloadParserFactories_;
 		FullPayloadSerializerCollection payloadSerializers_;
@@ -110,7 +112,10 @@ class Server {
 int main() {
 	SimpleEventLoop eventLoop;
 	SimpleUserRegistry userRegistry;
-	userRegistry.addUser(JID("remko@limber"), "pass");
+	userRegistry.addUser(JID("remko@localhost"), "remko");
+	userRegistry.addUser(JID("kevin@localhost"), "kevin");
+	userRegistry.addUser(JID("remko@limber.swift.im"), "remko");
+	userRegistry.addUser(JID("kevin@limber.swift.im"), "kevin");
 	Server server(&userRegistry);
 	eventLoop.run();
 	return 0;
diff --git a/Swiften/Client/Session.cpp b/Swiften/Client/Session.cpp
index 087880f..dbeddb7 100644
--- a/Swiften/Client/Session.cpp
+++ b/Swiften/Client/Session.cpp
@@ -31,20 +31,12 @@ Session::Session(const JID& jid, ConnectionFactory* connectionFactory, TLSLayerF
 		payloadSerializers_(payloadSerializers),
 		state_(Initial), 
 		error_(NoError),
-		xmppLayer_(0), 
-		tlsLayer_(0),
-		connectionLayer_(0), 
-		whitespacePingLayer_(0),
 		streamStack_(0),
 		needSessionStart_(false) {
 }
 
 Session::~Session() {
 	delete streamStack_;
-	delete whitespacePingLayer_;
-	delete connectionLayer_;
-	delete tlsLayer_;
-	delete xmppLayer_;
 }
 
 void Session::start() {
@@ -73,13 +65,13 @@ void Session::sendStreamHeader() {
 }
 
 void Session::initializeStreamStack() {
-	xmppLayer_ = new XMPPLayer(payloadParserFactories_, payloadSerializers_);
+	xmppLayer_ = boost::shared_ptr<XMPPLayer>(new XMPPLayer(payloadParserFactories_, payloadSerializers_));
 	xmppLayer_->onStreamStart.connect(boost::bind(&Session::handleStreamStart, this));
 	xmppLayer_->onElement.connect(boost::bind(&Session::handleElement, this, _1));
 	xmppLayer_->onError.connect(boost::bind(&Session::setError, this, XMLError));
 	xmppLayer_->onDataRead.connect(boost::bind(boost::ref(onDataRead), _1));
 	xmppLayer_->onWriteData.connect(boost::bind(boost::ref(onDataWritten), _1));
-	connectionLayer_ = new ConnectionLayer(connection_);
+	connectionLayer_ = boost::shared_ptr<ConnectionLayer>(new ConnectionLayer(connection_));
 	streamStack_ = new StreamStack(xmppLayer_, connectionLayer_);
 }
 
@@ -144,7 +136,7 @@ void Session::handleElement(boost::shared_ptr<Element> element) {
 			// Start the session
 
 			// Add a whitespace ping layer
-			whitespacePingLayer_ = new WhitespacePingLayer();
+			whitespacePingLayer_ = boost::shared_ptr<WhitespacePingLayer>(new WhitespacePingLayer());
 			streamStack_->addLayer(whitespacePingLayer_);
 
 			if (streamFeatures->hasSession()) {
diff --git a/Swiften/Client/Session.h b/Swiften/Client/Session.h
index 72b57bd..1b4d1fe 100644
--- a/Swiften/Client/Session.h
+++ b/Swiften/Client/Session.h
@@ -113,10 +113,10 @@ namespace Swift {
 			State state_;
 			SessionError error_;
 			boost::shared_ptr<Connection> connection_;
-			XMPPLayer* xmppLayer_;
-			TLSLayer* tlsLayer_;
-			ConnectionLayer* connectionLayer_;
-			WhitespacePingLayer* whitespacePingLayer_;
+			boost::shared_ptr<XMPPLayer> xmppLayer_;
+			boost::shared_ptr<TLSLayer> tlsLayer_;
+			boost::shared_ptr<ConnectionLayer> connectionLayer_;
+			boost::shared_ptr<WhitespacePingLayer> whitespacePingLayer_;
 			StreamStack* streamStack_;
 			bool needSessionStart_;
 			PKCS12Certificate certificate_;
diff --git a/Swiften/Client/UnitTest/SessionTest.cpp b/Swiften/Client/UnitTest/SessionTest.cpp
index f7f1db0..5d43736 100644
--- a/Swiften/Client/UnitTest/SessionTest.cpp
+++ b/Swiften/Client/UnitTest/SessionTest.cpp
@@ -718,23 +718,23 @@ class SessionTest : public CppUnit::TestFixture {
 			MockTLSLayerFactory() : haveTLS_(true) {}
 			void setTLSSupported(bool b) { haveTLS_ = b; }
 			virtual bool canCreate() const { return haveTLS_; }
-			virtual TLSLayer* createTLSLayer() { 
+			virtual boost::shared_ptr<TLSLayer> createTLSLayer() { 
 				assert(haveTLS_);
-				MockTLSLayer* result = new MockTLSLayer();
+				boost::shared_ptr<MockTLSLayer> result(new MockTLSLayer());
 				layers_.push_back(result);
 				return result;
 			}
-			std::vector<MockTLSLayer*> layers_;
+			std::vector< boost::shared_ptr<MockTLSLayer> > layers_;
 			bool haveTLS_;
 		};
 
 		struct MockSession : public Session {
 			MockSession(const JID& jid, ConnectionFactory* connectionFactory, TLSLayerFactory* tlsLayerFactory, PayloadParserFactoryCollection* payloadParserFactories, PayloadSerializerCollection* payloadSerializers) : Session(jid, connectionFactory, tlsLayerFactory, payloadParserFactories, payloadSerializers) {}
 
-			MockTLSLayer* getTLSLayer() const {
+			boost::shared_ptr<MockTLSLayer> getTLSLayer() const {
 				return getStreamStack()->getLayer<MockTLSLayer>();
 			}
-			WhitespacePingLayer* getWhitespacePingLayer() const {
+			boost::shared_ptr<WhitespacePingLayer> getWhitespacePingLayer() const {
 				return getStreamStack()->getLayer<WhitespacePingLayer>();
 			}
 		};
diff --git a/Swiften/EventLoop/MainEventLoop.h b/Swiften/EventLoop/MainEventLoop.h
index 0046546..fbb7079 100644
--- a/Swiften/EventLoop/MainEventLoop.h
+++ b/Swiften/EventLoop/MainEventLoop.h
@@ -19,7 +19,7 @@ namespace Swift {
 			 * If the owner is destroyed, all events should be removed from the
 			 * loop using removeEventsFromOwner().
 			 */
-			static void postEvent(boost::function<void ()> event, boost::shared_ptr<EventOwner> owner = 0);
+			static void postEvent(boost::function<void ()> event, boost::shared_ptr<EventOwner> owner = boost::shared_ptr<EventOwner>());
 
 			static void removeEventsFromOwner(boost::shared_ptr<EventOwner> owner);
 
diff --git a/Swiften/EventLoop/UnitTest/EventLoopTest.cpp b/Swiften/EventLoop/UnitTest/EventLoopTest.cpp
index c64d1ad..9475ac9 100644
--- a/Swiften/EventLoop/UnitTest/EventLoopTest.cpp
+++ b/Swiften/EventLoop/UnitTest/EventLoopTest.cpp
@@ -3,6 +3,7 @@
 #include <boost/thread.hpp>
 #include <boost/bind.hpp>
 
+#include "Swiften/EventLoop/EventOwner.h"
 #include "Swiften/EventLoop/SimpleEventLoop.h"
 #include "Swiften/Base/sleep.h"
 
@@ -25,8 +26,8 @@ class EventLoopTest : public CppUnit::TestFixture
 		void testPost() {
 			SimpleEventLoop testling;
 
-			testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 1), 0);
-			testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 2), 0);
+			testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 1));
+			testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 2));
 			testling.stop();
 			testling.run();
 
@@ -37,12 +38,14 @@ class EventLoopTest : public CppUnit::TestFixture
 
 		void testRemove() {
 			SimpleEventLoop testling;
+			boost::shared_ptr<MyEventOwner> eventOwner1(new MyEventOwner());
+			boost::shared_ptr<MyEventOwner> eventOwner2(new MyEventOwner());
 
-			testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 1), &testling);
-			testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 2), this);
-			testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 3), &testling);
-			testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 4), this);
-			testling.removeEventsFromOwner(this);
+			testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 1), eventOwner1);
+			testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 2), eventOwner2);
+			testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 3), eventOwner1);
+			testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 4), eventOwner2);
+			testling.removeEventsFromOwner(eventOwner2);
 			testling.stop();
 			testling.run();
 
@@ -52,6 +55,7 @@ class EventLoopTest : public CppUnit::TestFixture
 		}
 	
 	private:
+		struct MyEventOwner : public EventOwner {};
 		void logEvent(int i) {
 			events_.push_back(i);
 		}
diff --git a/Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp b/Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp
index a39aa9a..b6c2da8 100644
--- a/Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp
+++ b/Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp
@@ -32,7 +32,7 @@ class SimpleEventLoopTest : public CppUnit::TestFixture
 
 		void testPostFromMainThread() {
 			SimpleEventLoop testling;
-			testling.postEvent(boost::bind(&SimpleEventLoopTest::incrementCounterAndStop, this, &testling), 0);
+			testling.postEvent(boost::bind(&SimpleEventLoopTest::incrementCounterAndStop, this, &testling));
 			testling.run();
 
 			CPPUNIT_ASSERT_EQUAL(1, counter_);
@@ -42,7 +42,7 @@ class SimpleEventLoopTest : public CppUnit::TestFixture
 		void runIncrementingThread(SimpleEventLoop* loop) {
 			for (unsigned int i = 0; i < 10; ++i) {
         Swift::sleep(1);
-				loop->postEvent(boost::bind(&SimpleEventLoopTest::incrementCounter, this), 0);
+				loop->postEvent(boost::bind(&SimpleEventLoopTest::incrementCounter, this));
 			}
 			loop->stop();
 		}
diff --git a/Swiften/Network/BoostConnection.cpp b/Swiften/Network/BoostConnection.cpp
index ff53289..f837b50 100644
--- a/Swiften/Network/BoostConnection.cpp
+++ b/Swiften/Network/BoostConnection.cpp
@@ -42,7 +42,6 @@ BoostConnection::BoostConnection(boost::asio::io_service* ioService) :
 }
 
 BoostConnection::~BoostConnection() {
-	MainEventLoop::removeEventsFromOwner(shared_from_this());
 }
 
 void BoostConnection::listen() {
@@ -65,6 +64,7 @@ void BoostConnection::connect(const String& domain) {
 }
 
 void BoostConnection::disconnect() {
+	//MainEventLoop::removeEventsFromOwner(shared_from_this());
 	socket_.close();
 }
 
diff --git a/Swiften/Network/Timer.cpp b/Swiften/Network/Timer.cpp
index bab41e4..8999113 100644
--- a/Swiften/Network/Timer.cpp
+++ b/Swiften/Network/Timer.cpp
@@ -12,7 +12,7 @@ Timer::Timer(int milliseconds) :
 }
 
 Timer::~Timer() {
-	MainEventLoop::removeEventsFromOwner(shared_from_this());
+	//MainEventLoop::removeEventsFromOwner(shared_from_this());
   ioService_->stop();
   thread_->join();
 	delete timer_;
diff --git a/Swiften/QA/ClientTest/ClientTest.cpp b/Swiften/QA/ClientTest/ClientTest.cpp
index 01b9647..b628a8d 100644
--- a/Swiften/QA/ClientTest/ClientTest.cpp
+++ b/Swiften/QA/ClientTest/ClientTest.cpp
@@ -45,8 +45,8 @@ int main(int, char**) {
 
 	{
 		boost::shared_ptr<Timer> timer(new Timer(10000));
-		timer.onTick.connect(boost::bind(&SimpleEventLoop::stop, &eventLoop));
-		timer.start();
+		timer->onTick.connect(boost::bind(&SimpleEventLoop::stop, &eventLoop));
+		timer->start();
 
 		eventLoop.run();
 	}
diff --git a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp
index d29739e..e38b895 100644
--- a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp
+++ b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp
@@ -20,13 +20,13 @@ class BoostConnectionTest : public CppUnit::TestFixture {
 		BoostConnectionTest() {}
 
 		void setUp() {
-			eventLoop_ = new DummyEventLoop();
 			boostIOServiceThread_ = new BoostIOServiceThread();
+			eventLoop_ = new DummyEventLoop();
 		}
 
 		void tearDown() {
-			delete boostIOServiceThread_;
 			delete eventLoop_;
+			delete boostIOServiceThread_;
 		}
 
 		void testDestructor() {
diff --git a/Swiften/Server/ServerFromClientSession.cpp b/Swiften/Server/ServerFromClientSession.cpp
index 6d4aba1..67067c5 100644
--- a/Swiften/Server/ServerFromClientSession.cpp
+++ b/Swiften/Server/ServerFromClientSession.cpp
@@ -31,7 +31,7 @@ ServerFromClientSession::ServerFromClientSession(
 			userRegistry_(userRegistry),
 			authenticated_(false),
 			initialized_(false) {
-	xmppLayer_ = new XMPPLayer(payloadParserFactories_, payloadSerializers_);
+	xmppLayer_ = boost::shared_ptr<XMPPLayer>(new XMPPLayer(payloadParserFactories_, payloadSerializers_));
 	xmppLayer_->onStreamStart.connect(
 			boost::bind(&ServerFromClientSession::handleStreamStart, this, _2));
 	xmppLayer_->onElement.connect(
@@ -42,14 +42,12 @@ ServerFromClientSession::ServerFromClientSession(
 			boost::bind(boost::ref(onDataRead), _1));
 	xmppLayer_->onWriteData.connect(
 			boost::bind(boost::ref(onDataWritten), _1));
-	connectionLayer_ = new ConnectionLayer(connection_);
+	connectionLayer_ = boost::shared_ptr<ConnectionLayer>(new ConnectionLayer(connection_));
 	streamStack_ = new StreamStack(xmppLayer_, connectionLayer_);
 }
 
 ServerFromClientSession::~ServerFromClientSession() {
 	delete streamStack_;
-	delete connectionLayer_;
-	delete xmppLayer_;
 }
 
 void ServerFromClientSession::handleElement(boost::shared_ptr<Element> element) {
diff --git a/Swiften/Server/ServerFromClientSession.h b/Swiften/Server/ServerFromClientSession.h
index 9c37b3d..62e89ef 100644
--- a/Swiften/Server/ServerFromClientSession.h
+++ b/Swiften/Server/ServerFromClientSession.h
@@ -55,9 +55,9 @@ namespace Swift {
 			UserRegistry* userRegistry_;
 			bool authenticated_;
 			bool initialized_;
-			ConnectionLayer* connectionLayer_;
+			boost::shared_ptr<XMPPLayer> xmppLayer_;
+			boost::shared_ptr<ConnectionLayer> connectionLayer_;
 			StreamStack* streamStack_;
-			XMPPLayer* xmppLayer_;
 			JID domain_;
 			String user_;
 			JID jid_;
diff --git a/Swiften/StreamStack/PlatformTLSLayerFactory.cpp b/Swiften/StreamStack/PlatformTLSLayerFactory.cpp
index bb1abf1..40021ee 100644
--- a/Swiften/StreamStack/PlatformTLSLayerFactory.cpp
+++ b/Swiften/StreamStack/PlatformTLSLayerFactory.cpp
@@ -22,12 +22,12 @@ bool PlatformTLSLayerFactory::canCreate() const {
 #endif
 }
 
-TLSLayer* PlatformTLSLayerFactory::createTLSLayer() {
+boost::shared_ptr<TLSLayer> PlatformTLSLayerFactory::createTLSLayer() {
 #ifdef HAVE_OPENSSL
-	return new OpenSSLLayer();
+	return boost::shared_ptr<TLSLayer>(new OpenSSLLayer());
 #else
 	assert(false);
-	return 0;
+	return boost::shared_ptr<TLSLayer>();
 #endif
 }
 
diff --git a/Swiften/StreamStack/PlatformTLSLayerFactory.h b/Swiften/StreamStack/PlatformTLSLayerFactory.h
index 6ebee32..6c343b0 100644
--- a/Swiften/StreamStack/PlatformTLSLayerFactory.h
+++ b/Swiften/StreamStack/PlatformTLSLayerFactory.h
@@ -1,5 +1,4 @@
-#ifndef SWIFTEN_OpenSSLLayerFactory_H
-#define SWIFTEN_OpenSSLLayerFactory_H
+#pragma once
 
 #include "Swiften/StreamStack/TLSLayerFactory.h"
 
@@ -9,8 +8,6 @@ namespace Swift {
 			PlatformTLSLayerFactory();
 
 			bool canCreate() const;
-			virtual TLSLayer* createTLSLayer();
+			virtual boost::shared_ptr<TLSLayer> createTLSLayer();
 	};
 }
-
-#endif
diff --git a/Swiften/StreamStack/StreamStack.cpp b/Swiften/StreamStack/StreamStack.cpp
index 7dde858..9eb9b4e 100644
--- a/Swiften/StreamStack/StreamStack.cpp
+++ b/Swiften/StreamStack/StreamStack.cpp
@@ -2,25 +2,36 @@
 
 #include <boost/bind.hpp>
 
+#include "Swiften/Base/foreach.h"
 #include "Swiften/StreamStack/XMPPLayer.h"
 #include "Swiften/StreamStack/LowLayer.h"
 #include "Swiften/StreamStack/StreamLayer.h"
 
 namespace Swift {
 
-StreamStack::StreamStack(XMPPLayer* xmppLayer, LowLayer* physicalLayer) : xmppLayer_(xmppLayer), physicalLayer_(physicalLayer) {
+StreamStack::StreamStack(boost::shared_ptr<XMPPLayer> xmppLayer, boost::shared_ptr<LowLayer> physicalLayer) : xmppLayer_(xmppLayer), physicalLayer_(physicalLayer) {
 	xmppReadSlotConnection_ = physicalLayer_->onDataRead.connect(boost::bind(&XMPPLayer::parseData, xmppLayer_, _1));
 	xmppWriteSignalConnection_ = xmppLayer_->onWriteData.connect(boost::bind(&LowLayer::writeData, physicalLayer_, _1));
 }
 
-void StreamStack::addLayer(StreamLayer* newLayer) {
+StreamStack::~StreamStack() {
+	// Disconnect the write signal connections to break cyclic signal 
+	// dependencies. The read signal connections have
+	// to remain, since these can be reached from the main event loop.
+	xmppWriteSignalConnection_.disconnect();
+	foreach(const boost::bsignals::connection& connection, writeSignalConnections_) {
+		connection.disconnect();
+	}
+}
+
+void StreamStack::addLayer(boost::shared_ptr<StreamLayer> newLayer) {
 	xmppReadSlotConnection_.disconnect();
 	xmppWriteSignalConnection_.disconnect();
 
-	LowLayer* lowLayer = (layers_.empty() ? physicalLayer_ : *layers_.rbegin());
+	boost::shared_ptr<LowLayer> lowLayer = (layers_.empty() ? physicalLayer_ : *layers_.rbegin());
 
 	lowLayer->onDataRead.connect(boost::bind(&HighLayer::handleDataRead, newLayer, _1), boost::bsignals::at_front);
-	newLayer->onWriteData.connect(boost::bind(&LowLayer::writeData, lowLayer, _1), boost::bsignals::at_front);
+	writeSignalConnections_.push_back(newLayer->onWriteData.connect(boost::bind(&LowLayer::writeData, lowLayer, _1), boost::bsignals::at_front));
 	xmppWriteSignalConnection_ = xmppLayer_->onWriteData.connect(boost::bind(&LowLayer::writeData, newLayer, _1), boost::bsignals::at_front);
 	xmppReadSlotConnection_ = newLayer->onDataRead.connect(boost::bind(&XMPPLayer::parseData, xmppLayer_, _1), boost::bsignals::at_front);
 	layers_.push_back(newLayer);
diff --git a/Swiften/StreamStack/StreamStack.h b/Swiften/StreamStack/StreamStack.h
index bc2e89b..87c522d 100644
--- a/Swiften/StreamStack/StreamStack.h
+++ b/Swiften/StreamStack/StreamStack.h
@@ -1,5 +1,4 @@
-#ifndef SWIFTEN_STREAMSTACK_H
-#define SWIFTEN_STREAMSTACK_H
+#pragma once
 
 #include <boost/shared_ptr.hpp>
 #include <boost/signal.hpp>
@@ -15,31 +14,31 @@ namespace Swift {
 
 	class StreamStack {
 		public:
-			StreamStack(XMPPLayer* xmppLayer, LowLayer* physicalLayer);
+			StreamStack(boost::shared_ptr<XMPPLayer> xmppLayer, boost::shared_ptr<LowLayer> physicalLayer);
+			~StreamStack();
 
-			void addLayer(StreamLayer*);
+			void addLayer(boost::shared_ptr<StreamLayer>);
 
-			XMPPLayer* getXMPPLayer() const {
+			boost::shared_ptr<XMPPLayer> getXMPPLayer() const {
 				return xmppLayer_;
 			}
 
-			template<typename T> T* getLayer() {
-				foreach(StreamLayer* streamLayer, layers_) {
-					T* layer = dynamic_cast<T*>(streamLayer);
+			template<typename T> boost::shared_ptr<T> getLayer() {
+				foreach(const boost::shared_ptr<StreamLayer>& streamLayer, layers_) {
+					boost::shared_ptr<T> layer = boost::dynamic_pointer_cast<T>(streamLayer);
 					if (layer) {
 						return layer;
 					}
 				}
-				return 0;
+				return boost::shared_ptr<T>();
 			}
 
 		private:
-			XMPPLayer* xmppLayer_;
-			LowLayer* physicalLayer_;
-			std::vector<StreamLayer*> layers_;
+			boost::shared_ptr<XMPPLayer> xmppLayer_;
+			boost::shared_ptr<LowLayer> physicalLayer_;
+			std::vector< boost::shared_ptr<StreamLayer> > layers_;
 			boost::bsignals::connection xmppReadSlotConnection_;
 			boost::bsignals::connection xmppWriteSignalConnection_;
+			std::vector< boost::bsignals::connection > writeSignalConnections_;
 	};
 }
-
-#endif
diff --git a/Swiften/StreamStack/TLSLayerFactory.h b/Swiften/StreamStack/TLSLayerFactory.h
index b4218a5..1b0bfc1 100644
--- a/Swiften/StreamStack/TLSLayerFactory.h
+++ b/Swiften/StreamStack/TLSLayerFactory.h
@@ -1,5 +1,6 @@
-#ifndef SWIFTEN_TLSLayerFactory_H
-#define SWIFTEN_TLSLayerFactory_H
+#pragma once
+
+#include <boost/shared_ptr.hpp>
 
 namespace Swift {
 	class TLSLayer;
@@ -9,8 +10,6 @@ namespace Swift {
 			virtual ~TLSLayerFactory();
 			virtual bool canCreate() const = 0;
 
-			virtual TLSLayer* createTLSLayer() = 0;
+			virtual boost::shared_ptr<TLSLayer> createTLSLayer() = 0;
 	};
 }
-
-#endif
diff --git a/Swiften/StreamStack/UnitTest/StreamStackTest.cpp b/Swiften/StreamStack/UnitTest/StreamStackTest.cpp
index 1f6aad7..6b97c0d 100644
--- a/Swiften/StreamStack/UnitTest/StreamStackTest.cpp
+++ b/Swiften/StreamStack/UnitTest/StreamStackTest.cpp
@@ -29,15 +29,13 @@ class StreamStackTest : public CppUnit::TestFixture
 		StreamStackTest() {}
 
 		void setUp() {
-			physicalStream_ = new TestLowLayer();
-			xmppStream_ = new XMPPLayer(&parserFactories_, &serializers_);
+			physicalStream_ = boost::shared_ptr<TestLowLayer>(new TestLowLayer());
+			xmppStream_ = boost::shared_ptr<XMPPLayer>(new XMPPLayer(&parserFactories_, &serializers_));
 			elementsReceived_ = 0;
 			dataWriteReceived_ = 0;
 		}
 
 		void tearDown() {
-			delete physicalStream_;
-			delete xmppStream_;
 		}
 
 		void testWriteData_NoIntermediateStreamStack() {
@@ -51,8 +49,8 @@ class StreamStackTest : public CppUnit::TestFixture
 
 		void testWriteData_OneIntermediateStream() {
 			StreamStack testling(xmppStream_, physicalStream_);
-			std::auto_ptr<MyStreamLayer> xStream(new MyStreamLayer("X"));
-			testling.addLayer(xStream.get());
+			boost::shared_ptr<MyStreamLayer> xStream(new MyStreamLayer("X"));
+			testling.addLayer(xStream);
 
 			xmppStream_->writeData("foo");
 
@@ -62,10 +60,10 @@ class StreamStackTest : public CppUnit::TestFixture
 
 		void testWriteData_TwoIntermediateStreamStack() {
 			StreamStack testling(xmppStream_, physicalStream_);
-			std::auto_ptr<MyStreamLayer> xStream(new MyStreamLayer("X"));
-			std::auto_ptr<MyStreamLayer> yStream(new MyStreamLayer("Y"));
-			testling.addLayer(xStream.get());
-			testling.addLayer(yStream.get());
+			boost::shared_ptr<MyStreamLayer> xStream(new MyStreamLayer("X"));
+			boost::shared_ptr<MyStreamLayer> yStream(new MyStreamLayer("Y"));
+			testling.addLayer(xStream);
+			testling.addLayer(yStream);
 
 			xmppStream_->writeData("foo");
 
@@ -85,8 +83,8 @@ class StreamStackTest : public CppUnit::TestFixture
 		void testReadData_OneIntermediateStream() {
 			StreamStack testling(xmppStream_, physicalStream_);
 			xmppStream_->onElement.connect(boost::bind(&StreamStackTest::handleElement, this, _1));
-			std::auto_ptr<MyStreamLayer> xStream(new MyStreamLayer("<"));
-			testling.addLayer(xStream.get());
+			boost::shared_ptr<MyStreamLayer> xStream(new MyStreamLayer("<"));
+			testling.addLayer(xStream);
 
 			physicalStream_->onDataRead(ByteArray("stream:stream xmlns:stream='http://etherx.jabber.org/streams'><presence/>"));
 
@@ -96,10 +94,10 @@ class StreamStackTest : public CppUnit::TestFixture
 		void testReadData_TwoIntermediateStreamStack() {
 			StreamStack testling(xmppStream_, physicalStream_);
 			xmppStream_->onElement.connect(boost::bind(&StreamStackTest::handleElement, this, _1));
-			std::auto_ptr<MyStreamLayer> xStream(new MyStreamLayer("s"));
-			std::auto_ptr<MyStreamLayer> yStream(new MyStreamLayer("<"));
-			testling.addLayer(xStream.get());
-			testling.addLayer(yStream.get());
+			boost::shared_ptr<MyStreamLayer> xStream(new MyStreamLayer("s"));
+			boost::shared_ptr<MyStreamLayer> yStream(new MyStreamLayer("<"));
+			testling.addLayer(xStream);
+			testling.addLayer(yStream);
 
 			physicalStream_->onDataRead(ByteArray("tream:stream xmlns:stream='http://etherx.jabber.org/streams'><presence/>"));
 
@@ -109,8 +107,8 @@ class StreamStackTest : public CppUnit::TestFixture
 		void testAddLayer_ExistingOnWriteDataSlot() {
 			StreamStack testling(xmppStream_, physicalStream_);
 			xmppStream_->onWriteData.connect(boost::bind(&StreamStackTest::handleWriteData, this, _1));
-			std::auto_ptr<MyStreamLayer> xStream(new MyStreamLayer("X"));
-			testling.addLayer(xStream.get());
+			boost::shared_ptr<MyStreamLayer> xStream(new MyStreamLayer("X"));
+			testling.addLayer(xStream);
 
 			xmppStream_->writeData("foo");
 
@@ -158,8 +156,8 @@ class StreamStackTest : public CppUnit::TestFixture
 	private:
 		FullPayloadParserFactoryCollection parserFactories_;
 		FullPayloadSerializerCollection serializers_;
-		TestLowLayer* physicalStream_;
-		XMPPLayer* xmppStream_;
+		boost::shared_ptr<TestLowLayer> physicalStream_;
+		boost::shared_ptr<XMPPLayer> xmppStream_;
 		int elementsReceived_;
 		int dataWriteReceived_;
 };
-- 
cgit v0.10.2-6-g49f6