From 8c60e86c8fc2cf60825c0ffbd882693dccf0b33c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sun, 2 Aug 2009 15:57:54 +0200
Subject: Slimber: Handle conflicts/restarts.


diff --git a/Slimber/MainController.cpp b/Slimber/MainController.cpp
index d723f3f..4e238d2 100644
--- a/Slimber/MainController.cpp
+++ b/Slimber/MainController.cpp
@@ -16,8 +16,11 @@
 using namespace Swift;
 
 MainController::MainController(Menulet* menulet) : menulet(menulet) {
+	menuletController = new MenuletController(menulet);
+	menuletController->onRestartRequested.connect(boost::bind(
+			&MainController::handleRestartRequested, this));
+
 	dnsSDQuerier = boost::shared_ptr<BonjourQuerier>(new BonjourQuerier());
-	dnsSDQuerier->start();
 
 	linkLocalServiceBrowser = new LinkLocalServiceBrowser(dnsSDQuerier);
 	linkLocalServiceBrowser->onServiceAdded.connect(
@@ -26,7 +29,6 @@ MainController::MainController(Menulet* menulet) : menulet(menulet) {
 			boost::bind(&MainController::handleServicesChanged, this));
 	linkLocalServiceBrowser->onServiceChanged.connect(
 			boost::bind(&MainController::handleServicesChanged, this));
-	linkLocalServiceBrowser->start();
 
 	vCardCollection = new FileVCardCollection(
 			PlatformApplication("Slimber").getSettingsDir());
@@ -37,14 +39,7 @@ MainController::MainController(Menulet* menulet) : menulet(menulet) {
 	server->onSelfConnected.connect(
 			boost::bind(&MainController::handleSelfConnected, this, _1));
 
-	menuletController = new MenuletController(menulet);
-	menuletController->onRestartRequested.connect(boost::bind(
-			&MainController::handleRestartRequested, this));
-
-	handleSelfConnected(false);
-	handleServicesChanged();
-
-	server->start();
+	start();
 }
 
 MainController::~MainController() {
@@ -56,6 +51,22 @@ MainController::~MainController() {
 	dnsSDQuerier->stop();
 }
 
+void MainController::start() {
+	dnsSDQuerier->start();
+	linkLocalServiceBrowser->start();
+
+	handleSelfConnected(false);
+	handleServicesChanged();
+
+	server->start();
+}
+
+void MainController::stop() {
+	server->stop();
+	linkLocalServiceBrowser->stop();
+	dnsSDQuerier->stop();
+}
+
 void MainController::handleSelfConnected(bool b) {
 	if (b) {
 		menuletController->setXMPPStatus("You are logged in", MenuletController::Online);
@@ -84,4 +95,6 @@ void MainController::handleServerStopped(boost::optional<ServerError> error) {
 
 void MainController::handleRestartRequested() {
 	std::cout << "RESTART!" << std::endl;
+	stop();
+	start();
 }
diff --git a/Slimber/MainController.h b/Slimber/MainController.h
index 4ff9afd..2c74e4c 100644
--- a/Slimber/MainController.h
+++ b/Slimber/MainController.h
@@ -26,6 +26,9 @@ class MainController {
 		void handleServerStopped(boost::optional<Swift::ServerError> error);
 		void handleRestartRequested();
 
+		void start();
+		void stop();
+
 	private:
 		Menulet* menulet;
 		boost::shared_ptr<Swift::DNSSDQuerier> dnsSDQuerier;
diff --git a/Slimber/Server.cpp b/Slimber/Server.cpp
index 44a5861..28e0659 100644
--- a/Slimber/Server.cpp
+++ b/Slimber/Server.cpp
@@ -57,7 +57,6 @@ void Server::start() {
 			boost::bind(&Server::handleNewClientConnection, this, _1));
 	serverFromClientConnectionServer->onStopped.connect(
 			boost::bind(&Server::handleClientConnectionServerStopped, this, _1));
-	serverFromClientConnectionServer->start();
 
 	assert(!serverFromNetworkConnectionServer);
 	serverFromNetworkConnectionServer = 
@@ -65,9 +64,8 @@ void Server::start() {
 			linkLocalConnectionPort, &boostIOServiceThread.getIOService()));
 	serverFromNetworkConnectionServer->onNewConnection.connect(
 			boost::bind(&Server::handleNewLinkLocalConnection, this, _1));
-	serverFromClientConnectionServer->onStopped.connect(
+	serverFromNetworkConnectionServer->onStopped.connect(
 			boost::bind(&Server::handleLinkLocalConnectionServerStopped, this, _1));
-	serverFromNetworkConnectionServer->start();
 
 	assert(!presenceManager);
 	presenceManager = new LinkLocalPresenceManager(linkLocalServiceBrowser);
@@ -75,6 +73,9 @@ void Server::start() {
 			boost::bind(&Server::handleRosterChanged, this, _1));
 	presenceManager->onPresenceChanged.connect(
 			boost::bind(&Server::handlePresenceChanged, this, _1));
+
+	serverFromClientConnectionServer->start();
+	serverFromNetworkConnectionServer->start();
 }
 
 void Server::stop() {
@@ -89,6 +90,7 @@ void Server::stop(boost::optional<ServerError> e) {
 	stopping = true;
 
 	delete presenceManager;
+	presenceManager = NULL;
 
 	if (serverFromClientSession) {
 		serverFromClientSession->finishSession();
@@ -106,9 +108,13 @@ void Server::stop(boost::optional<ServerError> e) {
 
 	if (serverFromNetworkConnectionServer) {
 		serverFromNetworkConnectionServer->stop();
+		serverFromNetworkConnectionServer->cancelAllEvents();
+		serverFromNetworkConnectionServer.reset();
 	}
 	if (serverFromClientConnectionServer) {
 		serverFromClientConnectionServer->stop();
+		serverFromClientConnectionServer->cancelAllEvents();
+		serverFromClientConnectionServer.reset();
 	}
 
 	stopping = false;
@@ -344,6 +350,7 @@ void Server::handlePresenceChanged(boost::shared_ptr<Presence> presence) {
 }
 
 void Server::handleClientConnectionServerStopped(boost::optional<BoostConnectionServer::Error> e) {
+	std::cout << "Client server stoppedd " << (bool) e << std::endl;
 	if (e) {
 		if (*e == BoostConnectionServer::Conflict) {
 			stop(ServerError(ServerError::C2SPortConflict));
@@ -358,6 +365,7 @@ void Server::handleClientConnectionServerStopped(boost::optional<BoostConnection
 }
 
 void Server::handleLinkLocalConnectionServerStopped(boost::optional<BoostConnectionServer::Error> e) {
+	std::cout << "LL server stoppedd " << (bool) e << std::endl;
 	if (e) {
 		if (*e == BoostConnectionServer::Conflict) {
 			stop(ServerError(ServerError::LinkLocalPortConflict));
diff --git a/Swiften/Network/BoostConnectionServer.cpp b/Swiften/Network/BoostConnectionServer.cpp
index 596761a..97c1316 100644
--- a/Swiften/Network/BoostConnectionServer.cpp
+++ b/Swiften/Network/BoostConnectionServer.cpp
@@ -21,10 +21,10 @@ void BoostConnectionServer::start() {
 	}
 	catch (const boost::system::system_error& e) {
 		if (e.code() == boost::asio::error::address_in_use) {
-			onStopped(Conflict);
+			MainEventLoop::postEvent(boost::bind(boost::ref(onStopped), Conflict), shared_from_this());
 		}
 		else {
-			onStopped(UnknownError);
+			MainEventLoop::postEvent(boost::bind(boost::ref(onStopped), UnknownError), shared_from_this());
 		}
 	}
 }
@@ -39,7 +39,11 @@ void BoostConnectionServer::stop(boost::optional<Error> e) {
 		acceptor_->close();
 		acceptor_ = NULL;
 	}
-	onStopped(e);
+	MainEventLoop::postEvent(boost::bind(boost::ref(onStopped), e), shared_from_this());
+}
+
+void BoostConnectionServer::cancelAllEvents() {
+	MainEventLoop::removeEventsFromOwner(shared_from_this());
 }
 
 void BoostConnectionServer::acceptNextConnection() {
diff --git a/Swiften/Network/BoostConnectionServer.h b/Swiften/Network/BoostConnectionServer.h
index d8e5eb4..13d87a5 100644
--- a/Swiften/Network/BoostConnectionServer.h
+++ b/Swiften/Network/BoostConnectionServer.h
@@ -20,6 +20,7 @@ namespace Swift {
 
 			void start();
 			void stop();
+			virtual void cancelAllEvents();
 
 			boost::signal<void (boost::optional<Error>)> onStopped;
 
diff --git a/Swiften/Network/ConnectionServer.h b/Swiften/Network/ConnectionServer.h
index 539367d..9300092 100644
--- a/Swiften/Network/ConnectionServer.h
+++ b/Swiften/Network/ConnectionServer.h
@@ -10,6 +10,8 @@ namespace Swift {
 		public:
 			virtual ~ConnectionServer();
 
+			virtual void cancelAllEvents() = 0;
+
 			boost::signal<void (boost::shared_ptr<Connection>)> onNewConnection;
 	};
 }
-- 
cgit v0.10.2-6-g49f6