From 0930cd940963be0edfe7c80b4925babca0e01443 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Wed, 15 Jul 2009 09:42:18 +0200
Subject: Use shared_ptr for EventLoop owners.


diff --git a/Swiften/EventLoop/EventLoop.cpp b/Swiften/EventLoop/EventLoop.cpp
index cec149c..3c3c356 100644
--- a/Swiften/EventLoop/EventLoop.cpp
+++ b/Swiften/EventLoop/EventLoop.cpp
@@ -30,7 +30,7 @@ void EventLoop::handleEvent(const Event& event) {
 	}
 }
 
-void EventLoop::postEvent(boost::function<void ()> callback, void* owner) {
+void EventLoop::postEvent(boost::function<void ()> callback, boost::shared_ptr<EventOwner> owner) {
 	Event event(owner, callback);
 	{
 		boost::lock_guard<boost::mutex> lock(eventsMutex_);
@@ -41,7 +41,7 @@ void EventLoop::postEvent(boost::function<void ()> callback, void* owner) {
 	post(event);
 }
 
-void EventLoop::removeEventsFromOwner(void* owner) {
+void EventLoop::removeEventsFromOwner(boost::shared_ptr<EventOwner> owner) {
 		boost::lock_guard<boost::mutex> lock(eventsMutex_);
 		events_.remove_if(HasOwner(owner));
 }
diff --git a/Swiften/EventLoop/EventLoop.h b/Swiften/EventLoop/EventLoop.h
index 2f04f32..bf6f929 100644
--- a/Swiften/EventLoop/EventLoop.h
+++ b/Swiften/EventLoop/EventLoop.h
@@ -1,22 +1,22 @@
-#ifndef SWIFTEN_EventLoop_H
-#define SWIFTEN_EventLoop_H
+#pragma once
 
 #include <boost/function.hpp>
 #include <boost/thread/mutex.hpp>
 #include <list>
 
 namespace Swift {
+	class EventOwner;
 	class EventLoop {
 		public:
 			EventLoop();
 			virtual ~EventLoop();
 			
-			void postEvent(boost::function<void ()> event, void* owner);
-			void removeEventsFromOwner(void* owner);
+			void postEvent(boost::function<void ()> event, boost::shared_ptr<EventOwner> owner = boost::shared_ptr<EventOwner>());
+			void removeEventsFromOwner(boost::shared_ptr<EventOwner> owner);
 
 		protected:
 			struct Event {
-				Event(void* owner, const boost::function<void()>& callback) :
+				Event(boost::shared_ptr<EventOwner> owner, const boost::function<void()>& callback) :
 						owner(owner), callback(callback) {
 				}
 
@@ -25,7 +25,7 @@ namespace Swift {
 				}
 
 				unsigned int id;
-				void* owner;
+				boost::shared_ptr<EventOwner> owner;
 				boost::function<void()> callback;
 			};
 
@@ -39,14 +39,12 @@ namespace Swift {
 
 		private:
 			struct HasOwner {
-				HasOwner(void* owner) : owner(owner) {}
+				HasOwner(boost::shared_ptr<EventOwner> owner) : owner(owner) {}
 				bool operator()(const Event& event) { return event.owner == owner; }
-				void* owner;
+				boost::shared_ptr<EventOwner> owner;
 			};
 			boost::mutex eventsMutex_;
 			unsigned int nextEventID_;
 			std::list<Event> events_;
 	};
 }
-
-#endif
diff --git a/Swiften/EventLoop/EventOwner.cpp b/Swiften/EventLoop/EventOwner.cpp
new file mode 100644
index 0000000..4818b3c
--- /dev/null
+++ b/Swiften/EventLoop/EventOwner.cpp
@@ -0,0 +1,8 @@
+#include "Swiften/EventLoop/EventOwner.h"
+
+namespace Swift {
+
+EventOwner::~EventOwner() {
+}
+
+}
diff --git a/Swiften/EventLoop/EventOwner.h b/Swiften/EventLoop/EventOwner.h
new file mode 100644
index 0000000..8da95e0
--- /dev/null
+++ b/Swiften/EventLoop/EventOwner.h
@@ -0,0 +1,8 @@
+#pragma once
+
+namespace Swift {
+	class EventOwner {
+		public:
+			virtual ~EventOwner();
+	};
+}
diff --git a/Swiften/EventLoop/MainEventLoop.cpp b/Swiften/EventLoop/MainEventLoop.cpp
index c306d3f..d7de6c6 100644
--- a/Swiften/EventLoop/MainEventLoop.cpp
+++ b/Swiften/EventLoop/MainEventLoop.cpp
@@ -23,11 +23,11 @@ void MainEventLoop::resetInstance() {
 	instance_ = 0;
 }
 
-void MainEventLoop::postEvent(boost::function<void ()> event, void* owner) {
+void MainEventLoop::postEvent(boost::function<void ()> event, boost::shared_ptr<EventOwner> owner) {
 	getInstance()->postEvent(event, owner);
 }
 
-void MainEventLoop::removeEventsFromOwner(void* owner) {
+void MainEventLoop::removeEventsFromOwner(boost::shared_ptr<EventOwner> owner) {
 	getInstance()->removeEventsFromOwner(owner);
 }
 
diff --git a/Swiften/EventLoop/MainEventLoop.h b/Swiften/EventLoop/MainEventLoop.h
index f29dbd4..0046546 100644
--- a/Swiften/EventLoop/MainEventLoop.h
+++ b/Swiften/EventLoop/MainEventLoop.h
@@ -8,6 +8,7 @@
 
 namespace Swift {
 	class EventLoop;
+	class EventOwner;
 
 	class MainEventLoop {
 			friend class EventLoop;
@@ -18,9 +19,9 @@ namespace Swift {
 			 * If the owner is destroyed, all events should be removed from the
 			 * loop using removeEventsFromOwner().
 			 */
-			static void postEvent(boost::function<void ()> event, void* owner = 0);
+			static void postEvent(boost::function<void ()> event, boost::shared_ptr<EventOwner> owner = 0);
 
-			static void removeEventsFromOwner(void* owner);
+			static void removeEventsFromOwner(boost::shared_ptr<EventOwner> owner);
 
 			template<typename T>
 			static void deleteLater(T* t) {
diff --git a/Swiften/EventLoop/Makefile.inc b/Swiften/EventLoop/Makefile.inc
index 894b18d..3347ae6 100644
--- a/Swiften/EventLoop/Makefile.inc
+++ b/Swiften/EventLoop/Makefile.inc
@@ -1,4 +1,5 @@
 SWIFTEN_SOURCES += \
+  Swiften/EventLoop/EventOwner.cpp \
   Swiften/EventLoop/EventLoop.cpp \
   Swiften/EventLoop/SimpleEventLoop.cpp \
   Swiften/EventLoop/MainEventLoop.cpp
diff --git a/Swiften/EventLoop/SimpleEventLoop.cpp b/Swiften/EventLoop/SimpleEventLoop.cpp
index 96ad774..357e158 100644
--- a/Swiften/EventLoop/SimpleEventLoop.cpp
+++ b/Swiften/EventLoop/SimpleEventLoop.cpp
@@ -29,7 +29,7 @@ void SimpleEventLoop::run() {
 }
 
 void SimpleEventLoop::stop() {
-	postEvent(boost::bind(&SimpleEventLoop::doStop, this), 0);
+	postEvent(boost::bind(&SimpleEventLoop::doStop, this));
 }
 
 void SimpleEventLoop::doStop() {
diff --git a/Swiften/Network/BoostConnection.cpp b/Swiften/Network/BoostConnection.cpp
index ec15c96..ff53289 100644
--- a/Swiften/Network/BoostConnection.cpp
+++ b/Swiften/Network/BoostConnection.cpp
@@ -42,7 +42,7 @@ BoostConnection::BoostConnection(boost::asio::io_service* ioService) :
 }
 
 BoostConnection::~BoostConnection() {
-	MainEventLoop::removeEventsFromOwner(this);
+	MainEventLoop::removeEventsFromOwner(shared_from_this());
 }
 
 void BoostConnection::listen() {
@@ -55,10 +55,9 @@ void BoostConnection::connect(const String& domain) {
 		HostAddressPort addressPort = resolver.resolve(domain.getUTF8String());
 		boost::asio::ip::tcp::endpoint endpoint(	
 				boost::asio::ip::address::from_string(addressPort.getAddress().toString()), addressPort.getPort());
-		// Use shared_from_this
 		socket_.async_connect(
 				endpoint,
-				boost::bind(&BoostConnection::handleConnectFinished, this, boost::asio::placeholders::error));
+				boost::bind(&BoostConnection::handleConnectFinished, shared_from_this(), boost::asio::placeholders::error));
 	}
 	catch (const DomainNameResolveException& e) {
 		onError(DomainNameResolveError);
@@ -70,41 +69,39 @@ void BoostConnection::disconnect() {
 }
 
 void BoostConnection::write(const ByteArray& data) {
-	// Use shared_from_this
 	boost::asio::async_write(socket_, SharedBuffer(data),
-			boost::bind(&BoostConnection::handleDataWritten, this, boost::asio::placeholders::error));
+			boost::bind(&BoostConnection::handleDataWritten, shared_from_this(), boost::asio::placeholders::error));
 }
 
 void BoostConnection::handleConnectFinished(const boost::system::error_code& error) {
 	if (!error) {
-		MainEventLoop::postEvent(boost::bind(boost::ref(onConnected)), this);
+		MainEventLoop::postEvent(boost::bind(boost::ref(onConnected)), shared_from_this());
 		doRead();
 	}
 	else if (error != boost::asio::error::operation_aborted) {
-		MainEventLoop::postEvent(boost::bind(boost::ref(onError), ConnectionError), this);
+		MainEventLoop::postEvent(boost::bind(boost::ref(onError), ConnectionError), shared_from_this());
 	}
 }
 
 void BoostConnection::doRead() {
-	// Use shared_from_this
 	socket_.async_read_some(
 			boost::asio::buffer(readBuffer_),
-			boost::bind(&BoostConnection::handleSocketRead, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+			boost::bind(&BoostConnection::handleSocketRead, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
 }
 
 void BoostConnection::handleSocketRead(const boost::system::error_code& error, size_t bytesTransferred) {
 	if (!error) {
-		MainEventLoop::postEvent(boost::bind(boost::ref(onDataRead), ByteArray(&readBuffer_[0], bytesTransferred)), this);
+		MainEventLoop::postEvent(boost::bind(boost::ref(onDataRead), ByteArray(&readBuffer_[0], bytesTransferred)), shared_from_this());
 		doRead();
 	}
 	else if (error != boost::asio::error::operation_aborted) {
-		MainEventLoop::postEvent(boost::bind(boost::ref(onError), ReadError), this);
+		MainEventLoop::postEvent(boost::bind(boost::ref(onError), ReadError), shared_from_this());
 	}
 }
 
 void BoostConnection::handleDataWritten(const boost::system::error_code& error) {
 	if (error && error != boost::asio::error::operation_aborted) {
-		MainEventLoop::postEvent(boost::bind(boost::ref(onError), WriteError), this);
+		MainEventLoop::postEvent(boost::bind(boost::ref(onError), WriteError), shared_from_this());
 	}
 }
 
diff --git a/Swiften/Network/BoostConnection.h b/Swiften/Network/BoostConnection.h
index 85de926..76b6588 100644
--- a/Swiften/Network/BoostConnection.h
+++ b/Swiften/Network/BoostConnection.h
@@ -1,8 +1,10 @@
 #pragma once
 
 #include <boost/asio.hpp>
+#include <boost/enable_shared_from_this.hpp>
 
 #include "Swiften/Network/Connection.h"
+#include "Swiften/EventLoop/EventOwner.h"
 
 namespace boost {
 	class thread;
@@ -12,7 +14,7 @@ namespace boost {
 }
 
 namespace Swift {
-	class BoostConnection : public Connection {
+	class BoostConnection : public Connection, public EventOwner, public boost::enable_shared_from_this<BoostConnection> {
 		public:
 			BoostConnection(boost::asio::io_service* ioService);
 			~BoostConnection();
diff --git a/Swiften/Network/Timer.cpp b/Swiften/Network/Timer.cpp
index 8b2b57f..bab41e4 100644
--- a/Swiften/Network/Timer.cpp
+++ b/Swiften/Network/Timer.cpp
@@ -12,7 +12,7 @@ Timer::Timer(int milliseconds) :
 }
 
 Timer::~Timer() {
-	MainEventLoop::removeEventsFromOwner(this);
+	MainEventLoop::removeEventsFromOwner(shared_from_this());
   ioService_->stop();
   thread_->join();
 	delete timer_;
@@ -21,20 +21,20 @@ Timer::~Timer() {
 }
 
 void Timer::start() {
-	thread_ = new boost::thread(boost::bind(&Timer::doStart, this));
+	thread_ = new boost::thread(boost::bind(&Timer::doStart, shared_from_this()));
 }
 
 void Timer::doStart() {
 	timer_ = new boost::asio::deadline_timer(*ioService_);
 	timer_->expires_from_now(boost::posix_time::milliseconds(timeout_));
-	timer_->async_wait(boost::bind(&Timer::handleTimerTick, this));
+	timer_->async_wait(boost::bind(&Timer::handleTimerTick, shared_from_this()));
 	ioService_->run();
 }
 
 void Timer::handleTimerTick() {
-	MainEventLoop::postEvent(boost::bind(boost::ref(onTick)), this);
+	MainEventLoop::postEvent(boost::bind(boost::ref(onTick)), shared_from_this());
 	timer_->expires_from_now(boost::posix_time::milliseconds(timeout_));
-	timer_->async_wait(boost::bind(&Timer::handleTimerTick, this));
+	timer_->async_wait(boost::bind(&Timer::handleTimerTick, shared_from_this()));
 }
 
 }
diff --git a/Swiften/Network/Timer.h b/Swiften/Network/Timer.h
index 8e4b4c2..de97c13 100644
--- a/Swiften/Network/Timer.h
+++ b/Swiften/Network/Timer.h
@@ -1,12 +1,14 @@
-#ifndef SWIFTEN_Timer_H
-#define SWIFTEN_Timer_H
+#pragma once
 
 #include <boost/asio.hpp>
 #include <boost/signals.hpp>
 #include <boost/thread.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+#include "Swiften/EventLoop/EventOwner.h"
 
 namespace Swift {
-	class Timer {
+	class Timer : public EventOwner, public boost::enable_shared_from_this<Timer> {
 		public:
 			Timer(int milliseconds);
 			~Timer();
@@ -27,5 +29,3 @@ namespace Swift {
 			boost::asio::deadline_timer* timer_;
 	};
 }
-
-#endif
diff --git a/Swiften/QA/ClientTest/ClientTest.cpp b/Swiften/QA/ClientTest/ClientTest.cpp
index 163eacd..01b9647 100644
--- a/Swiften/QA/ClientTest/ClientTest.cpp
+++ b/Swiften/QA/ClientTest/ClientTest.cpp
@@ -44,7 +44,7 @@ int main(int, char**) {
 	client->connect();
 
 	{
-		Timer timer(10000);
+		boost::shared_ptr<Timer> timer(new Timer(10000));
 		timer.onTick.connect(boost::bind(&SimpleEventLoop::stop, &eventLoop));
 		timer.start();
 
diff --git a/Swiften/StreamStack/WhitespacePingLayer.cpp b/Swiften/StreamStack/WhitespacePingLayer.cpp
index b9fbbd1..b10ba1a 100644
--- a/Swiften/StreamStack/WhitespacePingLayer.cpp
+++ b/Swiften/StreamStack/WhitespacePingLayer.cpp
@@ -6,13 +6,9 @@ namespace Swift {
 static const int TIMEOUT_MILLISECONDS = 60000;
 
 WhitespacePingLayer::WhitespacePingLayer() {
-	timer_ = new Timer(TIMEOUT_MILLISECONDS);
-	timer_->onTick.connect(boost::bind(&WhitespacePingLayer::handleTimerTick, this));
-	timer_->start();
-}
-
-WhitespacePingLayer::~WhitespacePingLayer() {
-	delete timer_;
+	timer = boost::shared_ptr<Timer>(new Timer(TIMEOUT_MILLISECONDS));
+	timer->onTick.connect(boost::bind(&WhitespacePingLayer::handleTimerTick, this));
+	timer->start();
 }
 
 void WhitespacePingLayer::writeData(const ByteArray& data) {
diff --git a/Swiften/StreamStack/WhitespacePingLayer.h b/Swiften/StreamStack/WhitespacePingLayer.h
index 01fd3e3..ed0648b 100644
--- a/Swiften/StreamStack/WhitespacePingLayer.h
+++ b/Swiften/StreamStack/WhitespacePingLayer.h
@@ -1,7 +1,7 @@
-#ifndef SWIFTEN_WhitespacePingLayer_H
-#define SWIFTEN_WhitespacePingLayer_H
+#pragma once
 
 #include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
 
 #include "Swiften/StreamStack/StreamLayer.h"
 
@@ -11,7 +11,6 @@ namespace Swift {
 	class WhitespacePingLayer : public StreamLayer, boost::noncopyable {
 		public:
 			WhitespacePingLayer();
-			~WhitespacePingLayer();
 
 			void writeData(const ByteArray& data);
 			void handleDataRead(const ByteArray& data);
@@ -20,8 +19,6 @@ namespace Swift {
 			void handleTimerTick();
 
 		private:
-			Timer* timer_;
+			boost::shared_ptr<Timer> timer;
 	};
 }
-
-#endif
-- 
cgit v0.10.2-6-g49f6