From 23387492f571e8e6c46c6fa6196bf496249c9853 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Mon, 24 May 2010 15:15:31 +0200
Subject: Make connector shared to avoid a crash on login.

Resolves: #346

diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp
index 9c93a87..63a93a3 100644
--- a/Swiften/Client/Client.cpp
+++ b/Swiften/Client/Client.cpp
@@ -46,7 +46,7 @@ void Client::connect() {
 
 void Client::connect(const String& host) {
 	assert(!connector_);
-	connector_ = boost::shared_ptr<Connector>(new Connector(host, &resolver_, connectionFactory_, timerFactory_));
+	connector_ = Connector::create(host, &resolver_, connectionFactory_, timerFactory_);
 	connector_->onConnectFinished.connect(boost::bind(&Client::handleConnectorFinished, this, _1));
 	connector_->setTimeoutMilliseconds(60*1000);
 	connector_->start();
diff --git a/Swiften/Client/Client.h b/Swiften/Client/Client.h
index f40f273..92e89f1 100644
--- a/Swiften/Client/Client.h
+++ b/Swiften/Client/Client.h
@@ -10,6 +10,7 @@
 #include <boost/shared_ptr.hpp>
 
 #include "Swiften/Network/PlatformDomainNameResolver.h"
+#include "Swiften/Network/Connector.h"
 #include "Swiften/Base/Error.h"
 #include "Swiften/Client/ClientSession.h"
 #include "Swiften/Client/ClientError.h"
@@ -29,7 +30,6 @@ namespace Swift {
 	class TimerFactory;
 	class ClientSession;
 	class BasicSessionStream;
-	class Connector;
 
 	class Client : public StanzaChannel, public IQRouter, public boost::bsignals::trackable {
 		public:
@@ -71,7 +71,7 @@ namespace Swift {
 			JID jid_;
 			String password_;
 			IDGenerator idGenerator_;
-			boost::shared_ptr<Connector> connector_;
+			Connector::ref connector_;
 			ConnectionFactory* connectionFactory_;
 			TimerFactory* timerFactory_;
 			TLSLayerFactory* tlsLayerFactory_;
diff --git a/Swiften/Network/Connector.cpp b/Swiften/Network/Connector.cpp
index 056a075..34fdf0b 100644
--- a/Swiften/Network/Connector.cpp
+++ b/Swiften/Network/Connector.cpp
@@ -30,10 +30,10 @@ void Connector::start() {
 	assert(!timer);
 	queriedAllServices = false;
 	serviceQuery = resolver->createServiceQuery("_xmpp-client._tcp." + hostname);
-	serviceQuery->onResult.connect(boost::bind(&Connector::handleServiceQueryResult, this, _1));
+	serviceQuery->onResult.connect(boost::bind(&Connector::handleServiceQueryResult, shared_from_this(), _1));
 	if (timeoutMilliseconds > 0) {
 		timer = timerFactory->createTimer(timeoutMilliseconds);
-		timer->onTick.connect(boost::bind(&Connector::handleTimeout, this));
+		timer->onTick.connect(boost::bind(&Connector::handleTimeout, shared_from_this()));
 		timer->start();
 	}
 	serviceQuery->run();
@@ -42,7 +42,7 @@ void Connector::start() {
 void Connector::queryAddress(const String& hostname) {
 	assert(!addressQuery);
 	addressQuery = resolver->createAddressQuery(hostname);
-	addressQuery->onResult.connect(boost::bind(&Connector::handleAddressQueryResult, this, _1, _2));
+	addressQuery->onResult.connect(boost::bind(&Connector::handleAddressQueryResult, shared_from_this(), _1, _2));
 	addressQuery->run();
 }
 
@@ -112,7 +112,7 @@ void Connector::tryConnect(const HostAddressPort& target) {
 	assert(!currentConnection);
 	//std::cout << "Connector::tryConnect() " << target.getAddress().toString() << " " << target.getPort() << std::endl;
 	currentConnection = connectionFactory->createConnection();
-	currentConnection->onConnectFinished.connect(boost::bind(&Connector::handleConnectionConnectFinished, this, _1));
+	currentConnection->onConnectFinished.connect(boost::bind(&Connector::handleConnectionConnectFinished, shared_from_this(), _1));
 	currentConnection->connect(target);
 }
 
diff --git a/Swiften/Network/Connector.h b/Swiften/Network/Connector.h
index 39d63df..d283f2d 100644
--- a/Swiften/Network/Connector.h
+++ b/Swiften/Network/Connector.h
@@ -23,9 +23,13 @@ namespace Swift {
 	class ConnectionFactory;
 	class TimerFactory;
 
-	class Connector : public boost::bsignals::trackable {
+	class Connector : public boost::bsignals::trackable, public boost::enable_shared_from_this<Connector> {
 		public:
-			Connector(const String& hostname, DomainNameResolver*, ConnectionFactory*, TimerFactory*);
+			typedef boost::shared_ptr<Connector> ref;
+
+			static Connector::ref create(const String& hostname, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory) {
+				return Connector::ref(new Connector(hostname, resolver, connectionFactory, timerFactory));
+			}
 
 			void setTimeoutMilliseconds(int milliseconds);
 			void start();
@@ -33,6 +37,8 @@ namespace Swift {
 			boost::signal<void (boost::shared_ptr<Connection>)> onConnectFinished;
 
 		private:
+			Connector(const String& hostname, DomainNameResolver*, ConnectionFactory*, TimerFactory*);
+
 			void handleServiceQueryResult(const std::vector<DomainNameServiceQuery::Result>& result);
 			void handleAddressQueryResult(const std::vector<HostAddress>& address, boost::optional<DomainNameResolveError> error);
 			void queryAddress(const String& hostname);
@@ -45,6 +51,7 @@ namespace Swift {
 			void finish(boost::shared_ptr<Connection>);
 			void handleTimeout();
 
+
 		private:
 			String hostname;
 			DomainNameResolver* resolver;
diff --git a/Swiften/Network/UnitTest/ConnectorTest.cpp b/Swiften/Network/UnitTest/ConnectorTest.cpp
index 917d8a1..32a7157 100644
--- a/Swiften/Network/UnitTest/ConnectorTest.cpp
+++ b/Swiften/Network/UnitTest/ConnectorTest.cpp
@@ -55,7 +55,7 @@ class ConnectorTest : public CppUnit::TestFixture {
 		}
 
 		void testConnect() {
-			std::auto_ptr<Connector> testling(createConnector());
+			Connector::ref testling(createConnector());
 			resolver->addXMPPClientService("foo.com", host1);
 			resolver->addXMPPClientService("foo.com", host2);
 			resolver->addAddress("foo.com", host3.getAddress());
@@ -69,7 +69,7 @@ class ConnectorTest : public CppUnit::TestFixture {
 		}
 
 		void testConnect_NoSRVHost() {
-			std::auto_ptr<Connector> testling(createConnector());
+			Connector::ref testling(createConnector());
 			resolver->addAddress("foo.com", host3.getAddress());
 
 			testling->start();
@@ -81,7 +81,7 @@ class ConnectorTest : public CppUnit::TestFixture {
 		}
 
 		void testConnect_FirstAddressHostFails() {
-			std::auto_ptr<Connector> testling(createConnector());
+			Connector::ref testling(createConnector());
 
 			HostAddress address1("1.1.1.1");
 			HostAddress address2("2.2.2.2");
@@ -99,7 +99,7 @@ class ConnectorTest : public CppUnit::TestFixture {
 		}
 
 		void testConnect_NoHosts() {
-			std::auto_ptr<Connector> testling(createConnector());
+			Connector::ref testling(createConnector());
 
 			testling->start();
 			eventLoop->processEvents();
@@ -109,7 +109,7 @@ class ConnectorTest : public CppUnit::TestFixture {
 		}
 
 		void testConnect_FirstSRVHostFails() {
-			std::auto_ptr<Connector> testling(createConnector());
+			Connector::ref testling(createConnector());
 			resolver->addXMPPClientService("foo.com", host1);
 			resolver->addXMPPClientService("foo.com", host2);
 			connectionFactory->failingPorts.push_back(host1);
@@ -122,7 +122,7 @@ class ConnectorTest : public CppUnit::TestFixture {
 		}
 
 		void testConnect_AllSRVHostsFailWithoutFallbackHost() {
-			std::auto_ptr<Connector> testling(createConnector());
+			Connector::ref testling(createConnector());
 			resolver->addXMPPClientService("foo.com", host1);
 			resolver->addXMPPClientService("foo.com", host2);
 			connectionFactory->failingPorts.push_back(host1);
@@ -136,7 +136,7 @@ class ConnectorTest : public CppUnit::TestFixture {
 		}
 
 		void testConnect_AllSRVHostsFailWithFallbackHost() {
-			std::auto_ptr<Connector> testling(createConnector());
+			Connector::ref testling(createConnector());
 			resolver->addXMPPClientService("foo.com", host1);
 			resolver->addXMPPClientService("foo.com", host2);
 			resolver->addAddress("foo.com", host3.getAddress());
@@ -152,7 +152,7 @@ class ConnectorTest : public CppUnit::TestFixture {
 		}
 
 		void testConnect_SRVAndFallbackHostsFail() {
-			std::auto_ptr<Connector> testling(createConnector());
+			Connector::ref testling(createConnector());
 			resolver->addXMPPClientService("foo.com", host1);
 			resolver->addAddress("foo.com", host3.getAddress());
 			connectionFactory->failingPorts.push_back(host1);
@@ -166,7 +166,7 @@ class ConnectorTest : public CppUnit::TestFixture {
 		}
 
 		void testConnect_TimeoutDuringResolve() {
-			std::auto_ptr<Connector> testling(createConnector());
+			Connector::ref testling(createConnector());
 			testling->setTimeoutMilliseconds(10);
 			resolver->setIsResponsive(false);
 
@@ -180,7 +180,7 @@ class ConnectorTest : public CppUnit::TestFixture {
 		}
 
 		void testConnect_TimeoutDuringConnect() {
-			std::auto_ptr<Connector> testling(createConnector());
+			Connector::ref testling(createConnector());
 			testling->setTimeoutMilliseconds(10);
 			resolver->addXMPPClientService("foo.com", host1);
 			connectionFactory->isResponsive = false;
@@ -195,7 +195,7 @@ class ConnectorTest : public CppUnit::TestFixture {
 		}
 
 		void testConnect_NoTimeout() {
-			std::auto_ptr<Connector> testling(createConnector());
+			Connector::ref testling(createConnector());
 			testling->setTimeoutMilliseconds(10);
 			resolver->addXMPPClientService("foo.com", host1);
 
@@ -210,8 +210,8 @@ class ConnectorTest : public CppUnit::TestFixture {
 
 
 	private:
-		Connector* createConnector() {
-			Connector* connector = new Connector("foo.com", resolver, connectionFactory, timerFactory);
+		Connector::ref createConnector() {
+			Connector::ref connector = Connector::create("foo.com", resolver, connectionFactory, timerFactory);
 			connector->onConnectFinished.connect(boost::bind(&ConnectorTest::handleConnectorFinished, this, _1));
 			return connector;
 		}
-- 
cgit v0.10.2-6-g49f6