/* * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Swift; namespace Swift { PlatformDomainNameResolver::PlatformDomainNameResolver(IDNConverter* idnConverter, EventLoop* eventLoop) : idnConverter(idnConverter), eventLoop(eventLoop), stopRequested(false) { thread = new std::thread(boost::bind(&PlatformDomainNameResolver::run, this)); } PlatformDomainNameResolver::~PlatformDomainNameResolver() { stopRequested = true; addQueryToQueue(std::shared_ptr()); thread->join(); delete thread; } std::shared_ptr PlatformDomainNameResolver::createServiceQuery(const std::string& serviceLookupPrefix, const std::string& domain) { boost::optional encodedDomain = idnConverter->getIDNAEncoded(domain); std::string result; if (encodedDomain) { result = serviceLookupPrefix + *encodedDomain; } return std::make_shared(result, eventLoop, this); } std::shared_ptr PlatformDomainNameResolver::createAddressQuery(const std::string& name) { return std::make_shared(idnConverter->getIDNAEncoded(name), eventLoop, this); } void PlatformDomainNameResolver::run() { while (!stopRequested) { PlatformDomainNameQuery::ref query; { std::unique_lock lock(queueMutex); while (queue.empty()) { queueNonEmpty.wait(lock); } query = queue.front(); queue.pop_front(); } // Check whether we don't have a non-null query (used to stop the // resolver) if (query) { query->runBlocking(); } } } void PlatformDomainNameResolver::addQueryToQueue(PlatformDomainNameQuery::ref query) { { std::lock_guard lock(queueMutex); queue.push_back(query); } queueNonEmpty.notify_one(); } }