From d3ade7a21cf2cc5e394eccca302e20360052a164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Sat, 24 Apr 2010 18:58:52 +0200 Subject: Don't lookup duplicate discovered link-local services. This fixes a segfault due to the old query being deleted when a duplicate query is started. diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp index 0ef8c74..d8e7acf 100644 --- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp @@ -43,6 +43,7 @@ boost::shared_ptr FakeDNSSDQuerier::createResolveHost void FakeDNSSDQuerier::addRunningQuery(boost::shared_ptr query) { runningQueries.push_back(query); + allQueriesEverRun.push_back(query); if (boost::shared_ptr browseQuery = boost::dynamic_pointer_cast(query)) { foreach(const DNSSDServiceID& service, services) { MainEventLoop::postEvent(boost::bind(boost::ref(browseQuery->onServiceAdded), service), shared_from_this()); diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h index 7ff092d..ef7af02 100644 --- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h @@ -54,6 +54,18 @@ namespace Swift { void setBrowseError(); void setRegisterError(); + public: + template + std::vector< boost::shared_ptr > getAllQueriesEverRun() const { + std::vector< boost::shared_ptr > result; + foreach(const boost::shared_ptr& query, allQueriesEverRun) { + if (boost::shared_ptr resultQuery = boost::dynamic_pointer_cast(query)) { + result.push_back(resultQuery); + } + } + return result; + } + private: template std::vector< boost::shared_ptr > getQueries() const { @@ -69,6 +81,7 @@ namespace Swift { private: String domain; std::list< boost::shared_ptr > runningQueries; + std::list< boost::shared_ptr > allQueriesEverRun; std::set services; typedef std::map ServiceInfoMap; ServiceInfoMap serviceInfo; diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp index f865807..efd56e3 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp @@ -95,14 +95,16 @@ void LinkLocalServiceBrowser::handleServiceAdded(const DNSSDServiceID& service) if (selfService && service == *selfService) { return; } - boost::shared_ptr resolveQuery = querier->createResolveServiceQuery(service); - resolveQuery->onServiceResolved.connect( - boost::bind(&LinkLocalServiceBrowser::handleServiceResolved, this, service, _1)); - std::pair r = resolveQueries.insert(std::make_pair(service, resolveQuery)); - if (!r.second) { + + std::pair r = resolveQueries.insert(std::make_pair(service, boost::shared_ptr())); + if (r.second) { + // There was no existing query yet. Start a new query. + boost::shared_ptr resolveQuery = querier->createResolveServiceQuery(service); + resolveQuery->onServiceResolved.connect( + boost::bind(&LinkLocalServiceBrowser::handleServiceResolved, this, service, _1)); r.first->second = resolveQuery; + resolveQuery->start(); } - resolveQuery->start(); } void LinkLocalServiceBrowser::handleServiceRemoved(const DNSSDServiceID& service) { diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp index f754d50..4f53931 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp @@ -14,6 +14,7 @@ #include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" #include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" #include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h" +#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h" #include "Swiften/EventLoop/DummyEventLoop.h" using namespace Swift; @@ -26,6 +27,7 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { CPPUNIT_TEST(testServiceAdded_NoServiceInfo); CPPUNIT_TEST(testServiceAdded_RegisteredService); CPPUNIT_TEST(testServiceAdded_UnregisteredService); + CPPUNIT_TEST(testServiceAdded_Twice); CPPUNIT_TEST(testServiceChanged); CPPUNIT_TEST(testServiceRemoved); CPPUNIT_TEST(testServiceRemoved_UnregisteredService); @@ -178,6 +180,31 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { testling->stop(); } + void testServiceAdded_Twice() { + boost::shared_ptr testling = createTestling(); + testling->start(); + eventLoop->processEvents(); + + querier->setServiceInfo(*testServiceID,*testServiceInfo); + querier->addService(*testServiceID); + querier->addService(*testServiceID); + eventLoop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(1, static_cast(querier->getAllQueriesEverRun().size())); + CPPUNIT_ASSERT_EQUAL(1, static_cast(addedServices.size())); + CPPUNIT_ASSERT(addedServices[0].getID() == *testServiceID); + CPPUNIT_ASSERT_EQUAL(0, static_cast(changedServices.size())); + CPPUNIT_ASSERT_EQUAL(0, static_cast(removedServices.size())); + std::vector services = testling->getServices(); + CPPUNIT_ASSERT_EQUAL(1, static_cast(services.size())); + CPPUNIT_ASSERT(*testServiceID == services[0].getID()); + CPPUNIT_ASSERT(testServiceInfo->port == services[0].getPort()); + CPPUNIT_ASSERT(testServiceInfo->host == services[0].getHostname()); + + testling->stop(); + } + + void testServiceChanged() { boost::shared_ptr testling = createTestling(); testling->start(); -- cgit v0.10.2-6-g49f6