From 3260f09c55a6f06d9c3ac10f2eddbda68d94de4d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Fri, 12 Jun 2009 09:46:07 +0200
Subject: Do not register IQHandler in the constructor.

This can get us in all kinds of trouble, including that it makes it
impossible to use shared_ptr<> for Requests.

diff --git a/Swift/Controllers/XMPPRosterController.cpp b/Swift/Controllers/XMPPRosterController.cpp
index 6bbc964..8385f65 100644
--- a/Swift/Controllers/XMPPRosterController.cpp
+++ b/Swift/Controllers/XMPPRosterController.cpp
@@ -22,11 +22,12 @@ namespace Swift {
  * The controller does not gain ownership of these parameters.
  */
 XMPPRosterController::XMPPRosterController(IQRouter* iqRouter, boost::shared_ptr<XMPPRoster> xmppRoster)
- : IQHandler(iqRouter), iqRouter_(iqRouter), xmppRoster_(xmppRoster) {
+ : iqRouter_(iqRouter), xmppRoster_(xmppRoster) {
+	iqRouter_->addHandler(this);
 }
 
 XMPPRosterController::~XMPPRosterController() {
-
+	iqRouter_->removeHandler(this);
 }
 
 void XMPPRosterController::requestRoster() {
diff --git a/Swiften/Queries/IQHandler.cpp b/Swiften/Queries/IQHandler.cpp
index b5e7e49..81bd773 100644
--- a/Swiften/Queries/IQHandler.cpp
+++ b/Swiften/Queries/IQHandler.cpp
@@ -3,12 +3,7 @@
 
 namespace Swift {
 
-IQHandler::IQHandler(IQRouter* router) : router_(router) {
-	router_->addHandler(this);
-}
-
 IQHandler::~IQHandler() {
-	router_->removeHandler(this);
 }
 
 }
diff --git a/Swiften/Queries/IQHandler.h b/Swiften/Queries/IQHandler.h
index 7a8d008..7389b3a 100644
--- a/Swiften/Queries/IQHandler.h
+++ b/Swiften/Queries/IQHandler.h
@@ -10,18 +10,9 @@ namespace Swift {
 
 	class IQHandler {
 		public:
-			IQHandler(IQRouter* router);
 			virtual ~IQHandler();
 
 			virtual bool handleIQ(boost::shared_ptr<IQ>) = 0;
-
-		protected:
-			IQRouter* getRouter() const {
-				return router_;
-			}
-	
-		private:
-			IQRouter* router_;
 	};
 }
 
diff --git a/Swiften/Queries/Request.cpp b/Swiften/Queries/Request.cpp
index 189bbaa..a788e91 100644
--- a/Swiften/Queries/Request.cpp
+++ b/Swiften/Queries/Request.cpp
@@ -4,17 +4,20 @@
 
 namespace Swift {
 
-Request::Request(IQ::Type type, const JID& receiver, boost::shared_ptr<Payload> payload, IQRouter* router, AutoDeleteBehavior autoDeleteBehavior) : IQHandler(router), type_(type), receiver_(receiver), payload_(payload), autoDeleteBehavior_(autoDeleteBehavior), sent_(false) {
-	id_ = getRouter()->getNewIQID();
+Request::Request(IQ::Type type, const JID& receiver, boost::shared_ptr<Payload> payload, IQRouter* router, AutoDeleteBehavior autoDeleteBehavior) : router_(router), type_(type), receiver_(receiver), payload_(payload), autoDeleteBehavior_(autoDeleteBehavior), sent_(false) {
 }
 
 void Request::send() {
+	assert(!sent_);
+	sent_ = true;
+
 	boost::shared_ptr<IQ> iq(new IQ(type_));
 	iq->setTo(receiver_);
 	iq->addPayload(payload_);
+	id_ = router_->getNewIQID();
 	iq->setID(id_);
-	sent_ = true;
-	getRouter()->sendIQ(iq);
+	router_->addHandler(this);
+	router_->sendIQ(iq);
 }
 
 bool Request::handleIQ(boost::shared_ptr<IQ> iq) {
@@ -27,6 +30,7 @@ bool Request::handleIQ(boost::shared_ptr<IQ> iq) {
 			// FIXME: Get proper error
 			handleResponse(boost::shared_ptr<Payload>(), boost::optional<Error>(Error::UndefinedCondition));
 		}
+		router_->removeHandler(this);
 		if (autoDeleteBehavior_ == AutoDeleteAfterResponse) {
 			MainEventLoop::deleteLater(this);
 		}
diff --git a/Swiften/Queries/Request.h b/Swiften/Queries/Request.h
index d2bede6..52d1d15 100644
--- a/Swiften/Queries/Request.h
+++ b/Swiften/Queries/Request.h
@@ -35,6 +35,7 @@ namespace Swift {
 			bool handleIQ(boost::shared_ptr<IQ>);
 
 		private:
+			IQRouter* router_;
 			IQ::Type type_;
 			JID receiver_;
 			boost::shared_ptr<Payload> payload_;
diff --git a/Swiften/Queries/Responder.h b/Swiften/Queries/Responder.h
index b6029ae..e6e8ca6 100644
--- a/Swiften/Queries/Responder.h
+++ b/Swiften/Queries/Responder.h
@@ -2,13 +2,19 @@
 #define SWIFTEN_Responder_H
 
 #include "Swiften/Queries/IQHandler.h"
+#include "Swiften/Queries/IQRouter.h"
 #include "Swiften/Elements/Error.h"
 
 namespace Swift {
 	template<typename PAYLOAD_TYPE>
 	class Responder : public IQHandler {
 		public:
-			Responder(IQRouter* router) : IQHandler(router) {
+			Responder(IQRouter* router) : router_(router) {
+				router_->addHandler(this);
+			}
+
+			~Responder() {
+				router_->removeHandler(this);
 			}
 
 		protected:
@@ -16,11 +22,11 @@ namespace Swift {
 			virtual bool handleSetRequest(const JID& from, const String& id, boost::shared_ptr<PAYLOAD_TYPE> payload) = 0;
 
 			void sendResponse(const JID& to, const String& id, boost::shared_ptr<Payload> payload) {
-				getRouter()->sendIQ(IQ::createResult(to, id, payload));
+				router_->sendIQ(IQ::createResult(to, id, payload));
 			}
 
 			void sendError(const JID& to, const String& id, Error::Condition condition, Error::Type type) {
-				getRouter()->sendIQ(IQ::createError(to, id, condition, type));
+				router_->sendIQ(IQ::createError(to, id, condition, type));
 			}
 
 		private:
@@ -36,13 +42,16 @@ namespace Swift {
 							result = handleGetRequest(iq->getFrom(), iq->getID(), payload);
 						}
 						if (!result) {
-							getRouter()->sendIQ(IQ::createError(iq->getFrom(), iq->getID(), Error::NotAllowed, Error::Cancel));
+							router_->sendIQ(IQ::createError(iq->getFrom(), iq->getID(), Error::NotAllowed, Error::Cancel));
 						}
 						return true;
 					}
 				}
 				return false;
 			}
+		
+		private:
+			IQRouter* router_;
 	};
 }
 
-- 
cgit v0.10.2-6-g49f6