From 30f99a2bcbbeb41bfd61768b98c243ebcfdf67c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Fri, 24 Jul 2009 20:07:47 +0200
Subject: Make BonjourQuerier thread-safe.


diff --git a/Swiften/LinkLocal/BonjourBrowseQuery.h b/Swiften/LinkLocal/BonjourBrowseQuery.h
index 6a50a61..6db108d 100644
--- a/Swiften/LinkLocal/BonjourBrowseQuery.h
+++ b/Swiften/LinkLocal/BonjourBrowseQuery.h
@@ -2,6 +2,7 @@
 
 #include "Swiften/LinkLocal/BonjourQuery.h"
 #include "Swiften/LinkLocal/DNSSDBrowseQuery.h"
+#include "Swiften/EventLoop/MainEventLoop.h"
 
 namespace Swift {
 	class BonjourQuerier;
@@ -11,7 +12,7 @@ namespace Swift {
 			BonjourBrowseQuery(boost::shared_ptr<BonjourQuerier> q) : BonjourQuery(q) {
 				DNSServiceErrorType result = DNSServiceBrowse(
 						&sdRef, 0, 0, "_presence._tcp", 0, 
-						&BonjourBrowseQuery::handleServiceDiscovered, this);
+						&BonjourBrowseQuery::handleServiceDiscoveredStatic, this);
 				if (result != kDNSServiceErr_NoError) {
 					std::cout << "Error" << std::endl;
 					// TODO
@@ -28,19 +29,21 @@ namespace Swift {
 			}
 
 		private:
-			static void handleServiceDiscovered(DNSServiceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain, void *context) {
+			static void handleServiceDiscoveredStatic(DNSServiceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain, void *context) {
+				static_cast<BonjourBrowseQuery*>(context)->handleServiceDiscovered(flags, interfaceIndex, errorCode, name, type, domain);
+			}
+
+			void handleServiceDiscovered(DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain) {
 				if (errorCode != kDNSServiceErr_NoError) {
 					return;
 				}
 				else {
-					BonjourBrowseQuery* query = static_cast<BonjourBrowseQuery*>(context);
 					LinkLocalServiceID service(name, type, domain, interfaceIndex);
-					std::cout << "Service discovered: " << name << std::endl;
 					if (flags & kDNSServiceFlagsAdd) {
-						query->onServiceAdded(service);
+						MainEventLoop::postEvent(boost::bind(boost::ref(onServiceAdded), service), shared_from_this());
 					}
 					else {
-						query->onServiceRemoved(service);
+						MainEventLoop::postEvent(boost::bind(boost::ref(onServiceRemoved), service), shared_from_this());
 					}
 				}
 			}
diff --git a/Swiften/LinkLocal/BonjourPublishQuery.h b/Swiften/LinkLocal/BonjourPublishQuery.h
index 4e7fd2f..a96e25a 100644
--- a/Swiften/LinkLocal/BonjourPublishQuery.h
+++ b/Swiften/LinkLocal/BonjourPublishQuery.h
@@ -4,6 +4,7 @@
 #include "Swiften/LinkLocal/DNSSDPublishQuery.h"
 #include "Swiften/LinkLocal/LinkLocalServiceInfo.h"
 #include "Swiften/Base/ByteArray.h"
+#include "Swiften/EventLoop/MainEventLoop.h"
 
 namespace Swift {
 	class BonjourQuerier;
@@ -15,7 +16,7 @@ namespace Swift {
 				DNSServiceErrorType result = DNSServiceRegister(
 						&sdRef, 0, 0, name.getUTF8Data(), "_presence._tcp", NULL, NULL, port, 
 						txtRecord.getSize(), txtRecord.getData(), 
-						&BonjourPublishQuery::handleServiceRegistered, this);
+						&BonjourPublishQuery::handleServicePublishedStatic, this);
 				if (result != kDNSServiceErr_NoError) {
 					// TODO
 					std::cerr << "Error creating service registration" << std::endl;
@@ -26,15 +27,23 @@ namespace Swift {
 				run();
 			}
 
+			void update(const LinkLocalService& info) {
+				boost::lock_guard<boost::mutex> lock(sdRefMutex);
+				ByteArray txtRecord = info.toTXTRecord();
+				DNSServiceUpdateRecord(sdRef, NULL, NULL, txtRecord.getSize(), txtRecord.getData(), 0);
+			}
+
 		private:
-			static void handleServiceRegistered(DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context) {
-				std::cout << "Publish finished " << name << std::endl;
-				BonjourPublishQuery* query = static_cast<BonjourPublishQuery*>(context);
+			static void handleServicePublishedStatic(DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context) {
+				static_cast<BonjourPublishQuery*>(context)->handleServicePublished(errorCode, name, regtype, domain);
+			}
+
+			void handleServicePublished(DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain) {
 				if (errorCode != kDNSServiceErr_NoError) {
-					query->onPublishFinished(boost::optional<LinkLocalServiceID>());
+					MainEventLoop::postEvent(boost::bind(boost::ref(onPublishFinished), boost::optional<LinkLocalServiceID>()), shared_from_this());
 				}
 				else {
-					query->onPublishFinished(boost::optional<LinkLocalServiceID>(LinkLocalServiceID(name, regtype, domain, 0)));
+					MainEventLoop::postEvent(boost::bind(boost::ref(onPublishFinished), boost::optional<LinkLocalServiceID>(LinkLocalServiceID(name, regtype, domain, 0))), shared_from_this());
 				}
 			}
 	};
diff --git a/Swiften/LinkLocal/BonjourQuerier.cpp b/Swiften/LinkLocal/BonjourQuerier.cpp
index 93259c1..3080869 100644
--- a/Swiften/LinkLocal/BonjourQuerier.cpp
+++ b/Swiften/LinkLocal/BonjourQuerier.cpp
@@ -5,7 +5,6 @@
 #include <netinet/in.h>
 #include <fcntl.h>
 
-#include "Swiften/EventLoop/MainEventLoop.h"
 #include "Swiften/LinkLocal/BonjourBrowseQuery.h"
 #include "Swiften/LinkLocal/BonjourPublishQuery.h"
 #include "Swiften/Base/foreach.h"
@@ -108,10 +107,9 @@ void BonjourQuerier::run() {
 
 		{
 			boost::lock_guard<boost::mutex> lock(runningQueriesMutex);
-			foreach(const boost::shared_ptr<BonjourQuery>& query, runningQueries) {
+			foreach(boost::shared_ptr<BonjourQuery> query, runningQueries) {
 				if (FD_ISSET(query->getSocketID(), &fdSet)) {
-					MainEventLoop::postEvent(
-							boost::bind(&BonjourQuery::processResult, query), shared_from_this());
+					query->processResult();
 				}
 			}
 		}
diff --git a/Swiften/LinkLocal/BonjourQuerier.h b/Swiften/LinkLocal/BonjourQuerier.h
index 5f69ad6..e5ffa49 100644
--- a/Swiften/LinkLocal/BonjourQuerier.h
+++ b/Swiften/LinkLocal/BonjourQuerier.h
@@ -6,7 +6,6 @@
 #include <boost/thread.hpp>
 #include <boost/thread/mutex.hpp>
 
-#include "Swiften/EventLoop/EventOwner.h"
 #include "Swiften/LinkLocal/DNSSDBrowseQuery.h"
 #include "Swiften/LinkLocal/DNSSDPublishQuery.h"
 #include "Swiften/LinkLocal/BonjourQuery.h"
@@ -14,9 +13,7 @@
 namespace Swift {
 	class LinkLocalServiceInfo;
 
-	class BonjourQuerier : 
-			public boost::enable_shared_from_this<BonjourQuerier>, 
-			public EventOwner {
+	class BonjourQuerier : public boost::enable_shared_from_this<BonjourQuerier> {
 		public:
 			BonjourQuerier();
 			~BonjourQuerier();
diff --git a/Swiften/LinkLocal/BonjourQuery.cpp b/Swiften/LinkLocal/BonjourQuery.cpp
index 965a845..a9c13fb 100644
--- a/Swiften/LinkLocal/BonjourQuery.cpp
+++ b/Swiften/LinkLocal/BonjourQuery.cpp
@@ -11,9 +11,7 @@ BonjourQuery::~BonjourQuery() {
 }
 
 void BonjourQuery::processResult() {
-	std::cout << "Process result" << std::endl;
 	boost::lock_guard<boost::mutex> lock(sdRefMutex);
-	std::cout << "DNSSDServiceProcessResult" << std::endl;
 	DNSServiceProcessResult(sdRef);
 }
 
diff --git a/Swiften/LinkLocal/BonjourQuery.h b/Swiften/LinkLocal/BonjourQuery.h
index 2a47f73..bdb91a4 100644
--- a/Swiften/LinkLocal/BonjourQuery.h
+++ b/Swiften/LinkLocal/BonjourQuery.h
@@ -5,10 +5,14 @@
 #include <boost/enable_shared_from_this.hpp>
 #include <boost/thread/mutex.hpp>
 
+#include "Swiften/EventLoop/EventOwner.h"
+
 namespace Swift {
 	class BonjourQuerier;
 
-	class BonjourQuery : public boost::enable_shared_from_this<BonjourQuery> {
+	class BonjourQuery : 
+			public EventOwner,
+			public boost::enable_shared_from_this<BonjourQuery> {
 		public:
 			BonjourQuery(boost::shared_ptr<BonjourQuerier>);
 			virtual ~BonjourQuery();
diff --git a/configure.in b/configure.in
index 3a10e2c..186bc3c 100644
--- a/configure.in
+++ b/configure.in
@@ -198,12 +198,11 @@ AC_CHECK_LIB(resolv, inet_aton)
 # DNSSD Service
 case $host in
 	*-*-cygwin*)
-    AC_DEFINE(HAVE_BONJOUR)
 		;;
 	*-mingw32*)
-    AC_DEFINE(HAVE_BONJOUR)
 		;;
 	*-*-darwin*)
+    AC_DEFINE(HAVE_BONJOUR)
 		;;
 	*)
     AX_AVAHI()
-- 
cgit v0.10.2-6-g49f6