From 154bf14ac15fc7bff918c20814b29b5cc3bc5ba4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Fri, 18 Jun 2010 23:17:26 +0200
Subject: Fix crash on reconnect.

BoostTimer isn't supposed to be constructed as a non-shared-ptr. Making
constructor private to avoid this error in the future.

diff --git a/Limber/.gitignore b/Limber/.gitignore
index 6c52f38..b095d75 100644
--- a/Limber/.gitignore
+++ b/Limber/.gitignore
@@ -1 +1,2 @@
 limber
+BuildVersion.h
diff --git a/Limber/main.cpp b/Limber/main.cpp
index 5719a8c..45c6931 100644
--- a/Limber/main.cpp
+++ b/Limber/main.cpp
@@ -30,7 +30,7 @@ using namespace Swift;
 class Server {
 	public:
 		Server(UserRegistry* userRegistry) : userRegistry_(userRegistry) {
-			serverFromClientConnectionServer_ = boost::shared_ptr<BoostConnectionServer>(new BoostConnectionServer(5222, &boostIOServiceThread_.getIOService()));
+			serverFromClientConnectionServer_ = BoostConnectionServer::create(5222, &boostIOServiceThread_.getIOService());
 			serverFromClientConnectionServer_->onNewConnection.connect(boost::bind(&Server::handleNewConnection, this, _1));
 			serverFromClientConnectionServer_->start();
 		}
diff --git a/Slimber/Server.cpp b/Slimber/Server.cpp
index 5b08d93..7ec3b66 100644
--- a/Slimber/Server.cpp
+++ b/Slimber/Server.cpp
@@ -56,9 +56,8 @@ Server::~Server() {
 
 void Server::start() {
 	assert(!serverFromClientConnectionServer);
-	serverFromClientConnectionServer = 
-			boost::shared_ptr<BoostConnectionServer>(new BoostConnectionServer(
-					clientConnectionPort, &boostIOServiceThread.getIOService()));
+	serverFromClientConnectionServer = BoostConnectionServer::create(
+					clientConnectionPort, &boostIOServiceThread.getIOService());
 	serverFromClientConnectionServerSignalConnections.push_back(
 		serverFromClientConnectionServer->onNewConnection.connect(
 				boost::bind(&Server::handleNewClientConnection, this, _1)));
@@ -67,9 +66,8 @@ void Server::start() {
 				boost::bind(&Server::handleClientConnectionServerStopped, this, _1)));
 
 	assert(!serverFromNetworkConnectionServer);
-	serverFromNetworkConnectionServer = 
-		boost::shared_ptr<BoostConnectionServer>(new BoostConnectionServer(
-			linkLocalConnectionPort, &boostIOServiceThread.getIOService()));
+	serverFromNetworkConnectionServer = BoostConnectionServer::create(
+			linkLocalConnectionPort, &boostIOServiceThread.getIOService());
 	serverFromNetworkConnectionServerSignalConnections.push_back(
 		serverFromNetworkConnectionServer->onNewConnection.connect(
 				boost::bind(&Server::handleNewLinkLocalConnection, this, _1)));
@@ -256,7 +254,7 @@ void Server::handleElementReceived(boost::shared_ptr<Element> element, boost::sh
 							new LinkLocalConnector(
 								*service,
 								linkLocalServiceBrowser->getQuerier(),
-								boost::shared_ptr<BoostConnection>(new BoostConnection(&boostIOServiceThread.getIOService()))));
+								BoostConnection::create(&boostIOServiceThread.getIOService())));
 					connector->onConnectFinished.connect(
 							boost::bind(&Server::handleConnectFinished, this, connector, _1));
 					connectors.push_back(connector);
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 3e3affd..4ca38cc 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -15,7 +15,6 @@
 #include "Swiften/Application/Application.h"
 #include "Swiften/Application/ApplicationMessageDisplay.h"
 #include "Swiften/Network/TimerFactory.h"
-#include "Swiften/Network/BoostTimerFactory.h"
 #include "Swiften/Network/BoostIOServiceThread.h"
 #include "Swiften/Network/MainBoostIOServiceThread.h"
 #include "Swift/Controllers/BuildVersion.h"
@@ -81,7 +80,6 @@ MainController::MainController(ChatWindowFactory* chatWindowFactory, MainWindowF
 	presenceSender_ = NULL;
 	client_ = NULL;
 	mucSearchController_ = NULL;
-	reconnectTimer_ = NULL;
 
 	timeBeforeNextReconnect_ = -1;
 	mucSearchWindowFactory_ = mucSearchWindowFactory;
@@ -170,8 +168,10 @@ void MainController::resetClient() {
 
 void MainController::handleConnected() {
 	timeBeforeNextReconnect_ = -1;
-	delete reconnectTimer_;
-	reconnectTimer_ = NULL;
+	if (reconnectTimer_) {
+		reconnectTimer_->stop();
+		reconnectTimer_.reset();
+	}
 	loginWindow_->setIsLoggingIn(false);
 	if (lastDisconnectError_) {
 		lastDisconnectError_->conclude();
@@ -395,7 +395,7 @@ void MainController::setReconnectTimer() {
 	} else {
 		timeBeforeNextReconnect_ = timeBeforeNextReconnect_ >= 150 ? 300 : timeBeforeNextReconnect_ * 2;
 	}
-	reconnectTimer_ = new BoostTimer(timeBeforeNextReconnect_ * 1000, &MainBoostIOServiceThread::getInstance().getIOService());
+	reconnectTimer_ = timerFactory_.createTimer(timeBeforeNextReconnect_ * 1000);
 	reconnectTimer_->onTick.connect(boost::bind(&MainController::reconnectAfterError, this));
 	reconnectTimer_->start();
 }
@@ -413,8 +413,10 @@ void MainController::signOut() {
 }
 
 void MainController::logout() {
-	delete reconnectTimer_;
-	reconnectTimer_ = 0;
+	if (reconnectTimer_) {
+		reconnectTimer_->stop();
+		reconnectTimer_.reset();
+	}
 	if (client_ /*&& client_->isAvailable()*/) {
 		client_->disconnect();
 	}
diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h
index ad2cac8..5fc5e8f 100644
--- a/Swift/Controllers/MainController.h
+++ b/Swift/Controllers/MainController.h
@@ -132,6 +132,6 @@ namespace Swift {
 			MUCSearchController* mucSearchController_;
 			MUCSearchWindowFactory* mucSearchWindowFactory_;
 			int timeBeforeNextReconnect_;
-			BoostTimer* reconnectTimer_;
+			Timer::ref reconnectTimer_;
 	};
 }
diff --git a/Swiften/Examples/ConnectivityTest/ConnectivityTest.cpp b/Swiften/Examples/ConnectivityTest/ConnectivityTest.cpp
index 5669be9..049802f 100644
--- a/Swiften/Examples/ConnectivityTest/ConnectivityTest.cpp
+++ b/Swiften/Examples/ConnectivityTest/ConnectivityTest.cpp
@@ -84,7 +84,7 @@ int main(int argc, char* argv[]) {
 	}
 
 	{
-		boost::shared_ptr<BoostTimer> timer(new BoostTimer(timeout, &MainBoostIOServiceThread::getInstance().getIOService()));
+		BoostTimer::ref timer(BoostTimer::create(timeout, &MainBoostIOServiceThread::getInstance().getIOService()));
 		timer->onTick.connect(boost::bind(&SimpleEventLoop::stop, &eventLoop));
 		timer->start();
 
diff --git a/Swiften/Examples/SendMessage/SendMessage.cpp b/Swiften/Examples/SendMessage/SendMessage.cpp
index efc12f6..2ba5f3b 100644
--- a/Swiften/Examples/SendMessage/SendMessage.cpp
+++ b/Swiften/Examples/SendMessage/SendMessage.cpp
@@ -72,7 +72,7 @@ int main(int argc, char* argv[]) {
 	}
 
 	{
-		boost::shared_ptr<BoostTimer> timer(new BoostTimer(30000, &MainBoostIOServiceThread::getInstance().getIOService()));
+		BoostTimer::ref timer(BoostTimer::create(30000, &MainBoostIOServiceThread::getInstance().getIOService()));
 		timer->onTick.connect(boost::bind(&SimpleEventLoop::stop, &eventLoop));
 		timer->start();
 
diff --git a/Swiften/Network/BoostConnection.h b/Swiften/Network/BoostConnection.h
index abe7eeb..8d3d444 100644
--- a/Swiften/Network/BoostConnection.h
+++ b/Swiften/Network/BoostConnection.h
@@ -22,9 +22,14 @@ namespace boost {
 namespace Swift {
 	class BoostConnection : public Connection, public EventOwner, public boost::enable_shared_from_this<BoostConnection> {
 		public:
-			BoostConnection(boost::asio::io_service* ioService);
+			typedef boost::shared_ptr<BoostConnection> ref;
+
 			~BoostConnection();
 
+			static ref create(boost::asio::io_service* ioService) {
+				return ref(new BoostConnection(ioService));
+			}
+
 			virtual void listen();
 			virtual void connect(const HostAddressPort& address);
 			virtual void disconnect();
@@ -35,6 +40,8 @@ namespace Swift {
 			}
 
 		private:
+			BoostConnection(boost::asio::io_service* ioService);
+
 			void handleConnectFinished(const boost::system::error_code& error);
 			void handleSocketRead(const boost::system::error_code& error, size_t bytesTransferred);
 			void handleDataWritten(const boost::system::error_code& error);
diff --git a/Swiften/Network/BoostConnectionFactory.cpp b/Swiften/Network/BoostConnectionFactory.cpp
index f84a26e..7ba9f48 100644
--- a/Swiften/Network/BoostConnectionFactory.cpp
+++ b/Swiften/Network/BoostConnectionFactory.cpp
@@ -13,7 +13,7 @@ BoostConnectionFactory::BoostConnectionFactory(boost::asio::io_service* ioServic
 }
 
 boost::shared_ptr<Connection> BoostConnectionFactory::createConnection() {
-	return boost::shared_ptr<Connection>(new BoostConnection(ioService));
+	return BoostConnection::create(ioService);
 }
 
 }
diff --git a/Swiften/Network/BoostConnectionServer.cpp b/Swiften/Network/BoostConnectionServer.cpp
index 51c1203..febe6c9 100644
--- a/Swiften/Network/BoostConnectionServer.cpp
+++ b/Swiften/Network/BoostConnectionServer.cpp
@@ -50,7 +50,7 @@ void BoostConnectionServer::stop(boost::optional<Error> e) {
 }
 
 void BoostConnectionServer::acceptNextConnection() {
-	boost::shared_ptr<BoostConnection> newConnection(new BoostConnection(&acceptor_->io_service()));
+	BoostConnection::ref newConnection(BoostConnection::create(&acceptor_->io_service()));
 	acceptor_->async_accept(newConnection->getSocket(), 
 		boost::bind(&BoostConnectionServer::handleAccept, shared_from_this(), newConnection, boost::asio::placeholders::error));
 }
diff --git a/Swiften/Network/BoostConnectionServer.h b/Swiften/Network/BoostConnectionServer.h
index 311be4b..3a3c096 100644
--- a/Swiften/Network/BoostConnectionServer.h
+++ b/Swiften/Network/BoostConnectionServer.h
@@ -18,18 +18,25 @@
 namespace Swift {
 	class BoostConnectionServer : public ConnectionServer, public EventOwner, public boost::enable_shared_from_this<BoostConnectionServer> {
 		public:
+			typedef boost::shared_ptr<BoostConnectionServer> ref;
+
 			enum Error {
 				Conflict,
 				UnknownError
 			};
-			BoostConnectionServer(int port, boost::asio::io_service* ioService);
 
+			static ref create(int port, boost::asio::io_service* ioService) {
+				return ref(new BoostConnectionServer(port, ioService));
+			}
+			
 			void start();
 			void stop();
 
 			boost::signal<void (boost::optional<Error>)> onStopped;
 
 		private:
+			BoostConnectionServer(int port, boost::asio::io_service* ioService);
+
 			void stop(boost::optional<Error> e);
 			void acceptNextConnection();
 			void handleAccept(boost::shared_ptr<BoostConnection> newConnection, const boost::system::error_code& error);
diff --git a/Swiften/Network/BoostTimer.h b/Swiften/Network/BoostTimer.h
index 85db864..f48cb36 100644
--- a/Swiften/Network/BoostTimer.h
+++ b/Swiften/Network/BoostTimer.h
@@ -16,12 +16,18 @@
 namespace Swift {
 	class BoostTimer : public Timer, public EventOwner, public boost::enable_shared_from_this<BoostTimer> {
 		public:
-			BoostTimer(int milliseconds, boost::asio::io_service* service);
+			typedef boost::shared_ptr<BoostTimer> ref;
+
+			static ref create(int milliseconds, boost::asio::io_service* service) {
+				return ref(new BoostTimer(milliseconds, service));
+			}
 
 			virtual void start();
 			virtual void stop();
 
 		private:
+			BoostTimer(int milliseconds, boost::asio::io_service* service);
+
 			void handleTimerTick(const boost::system::error_code& error);
 
 		private:
diff --git a/Swiften/Network/BoostTimerFactory.cpp b/Swiften/Network/BoostTimerFactory.cpp
index 7eec197..b22525c 100644
--- a/Swiften/Network/BoostTimerFactory.cpp
+++ b/Swiften/Network/BoostTimerFactory.cpp
@@ -13,7 +13,7 @@ BoostTimerFactory::BoostTimerFactory(boost::asio::io_service* ioService) : ioSer
 }
 
 boost::shared_ptr<Timer> BoostTimerFactory::createTimer(int milliseconds) {
-	return boost::shared_ptr<Timer>(new BoostTimer(milliseconds, ioService));
+	return BoostTimer::create(milliseconds, ioService);
 }
 
 }
diff --git a/Swiften/Network/Timer.h b/Swiften/Network/Timer.h
index 873837d..278a8fb 100644
--- a/Swiften/Network/Timer.h
+++ b/Swiften/Network/Timer.h
@@ -11,6 +11,8 @@
 namespace Swift {
 	class Timer {
 		public:
+			typedef boost::shared_ptr<Timer> ref;
+
 			virtual ~Timer();
 
 			virtual void start() = 0;
diff --git a/Swiften/Network/TimerFactory.h b/Swiften/Network/TimerFactory.h
index 558426c..44c87b6 100644
--- a/Swiften/Network/TimerFactory.h
+++ b/Swiften/Network/TimerFactory.h
@@ -8,13 +8,13 @@
 
 #include <boost/shared_ptr.hpp>
 
-namespace Swift {
-	class Timer;
+#include "Swiften/Network/Timer.h"
 
+namespace Swift {
 	class TimerFactory {
 		public:
 			virtual ~TimerFactory();
 
-			virtual boost::shared_ptr<Timer> createTimer(int milliseconds) = 0;
+			virtual Timer::ref createTimer(int milliseconds) = 0;
 	};
 }
diff --git a/Swiften/QA/ClientTest/ClientTest.cpp b/Swiften/QA/ClientTest/ClientTest.cpp
index cd95e70..872d6f2 100644
--- a/Swiften/QA/ClientTest/ClientTest.cpp
+++ b/Swiften/QA/ClientTest/ClientTest.cpp
@@ -61,7 +61,7 @@ int main(int, char**) {
 	client->connect();
 
 	{
-		boost::shared_ptr<BoostTimer> timer(new BoostTimer(30000, &MainBoostIOServiceThread::getInstance().getIOService()));
+		boost::shared_ptr<BoostTimer> timer(BoostTimer::create(30000, &MainBoostIOServiceThread::getInstance().getIOService()));
 		timer->onTick.connect(boost::bind(&SimpleEventLoop::stop, &eventLoop));
 		timer->start();
 
diff --git a/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp
index cf3535a..543e085 100644
--- a/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp
+++ b/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp
@@ -39,15 +39,15 @@ class BoostConnectionServerTest : public CppUnit::TestFixture {
 		}
 
 		void testConstructor_TwoServersOnSamePort() {
-			boost::shared_ptr<BoostConnectionServer> testling(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
-			boost::shared_ptr<BoostConnectionServer> testling2(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
+			BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, &boostIOServiceThread_->getIOService()));
+			BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, &boostIOServiceThread_->getIOService()));
 		}
 
 		void testStart_Conflict() {
-			boost::shared_ptr<BoostConnectionServer> testling(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
+			BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, &boostIOServiceThread_->getIOService()));
 			testling->start();
 
-			boost::shared_ptr<BoostConnectionServer> testling2(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
+			BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, &boostIOServiceThread_->getIOService()));
 			testling2->onStopped.connect(
 					boost::bind(&BoostConnectionServerTest::handleStopped, this, _1));
 
@@ -55,12 +55,12 @@ class BoostConnectionServerTest : public CppUnit::TestFixture {
 		}
 
 		void testStop() {
-			boost::shared_ptr<BoostConnectionServer> testling(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
+			BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, &boostIOServiceThread_->getIOService()));
 			testling->start();
 
 			testling->stop();
 
-			boost::shared_ptr<BoostConnectionServer> testling2(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
+			BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, &boostIOServiceThread_->getIOService()));
 			testling2->start();
 
 			testling2->stop();
diff --git a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp
index 28c8608..913f7c0 100644
--- a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp
+++ b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp
@@ -43,14 +43,14 @@ class BoostConnectionTest : public CppUnit::TestFixture {
 
 		void testDestructor() {
 			{
-				boost::shared_ptr<BoostConnection> testling(new BoostConnection(&boostIOServiceThread_->getIOService()));
+				BoostConnection::ref testling(BoostConnection::create(&boostIOServiceThread_->getIOService()));
 				testling->connect(HostAddressPort(HostAddress(address, 4), 5222));
 			}
 		}
 
 		void testDestructor_PendingEvents() {
 			{
-				boost::shared_ptr<BoostConnection> testling(new BoostConnection(&boostIOServiceThread_->getIOService()));
+				BoostConnection::ref testling(BoostConnection::create(&boostIOServiceThread_->getIOService()));
 				testling->connect(HostAddressPort(HostAddress(address, 4), 5222));
 				while (!eventLoop_->hasEvents()) {
 					Swift::sleep(10);
@@ -60,7 +60,7 @@ class BoostConnectionTest : public CppUnit::TestFixture {
 		}
 
 		void testWrite() {
-			boost::shared_ptr<BoostConnection> testling(new BoostConnection(&boostIOServiceThread_->getIOService()));
+			BoostConnection::ref testling(BoostConnection::create(&boostIOServiceThread_->getIOService()));
 			testling->onConnectFinished.connect(boost::bind(&BoostConnectionTest::doWrite, this, testling.get()));
 			testling->onDataRead.connect(boost::bind(&BoostConnectionTest::handleDataRead, this, _1));
 			testling->onDisconnected.connect(boost::bind(&BoostConnectionTest::handleDisconnected, this));
diff --git a/Swiften/QA/ReconnectTest/ReconnectTest.cpp b/Swiften/QA/ReconnectTest/ReconnectTest.cpp
index f630dd8..24be849 100644
--- a/Swiften/QA/ReconnectTest/ReconnectTest.cpp
+++ b/Swiften/QA/ReconnectTest/ReconnectTest.cpp
@@ -43,7 +43,7 @@ void handleTick(boost::shared_ptr<BoostTimer> timer) {
 	
 	int delay = 500;
 //	int delay = 0;
-	boost::shared_ptr<BoostTimer> newTimer(new BoostTimer(delay, &MainBoostIOServiceThread::getInstance().getIOService()));
+	boost::shared_ptr<BoostTimer> newTimer(BoostTimer::create(delay, &MainBoostIOServiceThread::getInstance().getIOService()));
 	newTimer->onTick.connect(boost::bind(&handleTick, timer));
 	newTimer->start();
 }
-- 
cgit v0.10.2-6-g49f6