summaryrefslogtreecommitdiffstats
path: root/src/network/kernel/qhostinfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/kernel/qhostinfo.cpp')
-rw-r--r--src/network/kernel/qhostinfo.cpp425
1 files changed, 292 insertions, 133 deletions
diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp
index f4348b690e..f9335c3bb9 100644
--- a/src/network/kernel/qhostinfo.cpp
+++ b/src/network/kernel/qhostinfo.cpp
@@ -37,13 +37,17 @@
**
****************************************************************************/
+//#define QHOSTINFO_DEBUG
+
#include "qhostinfo.h"
#include "qhostinfo_p.h"
+#include <qplatformdefs.h>
#include "QtCore/qscopedpointer.h"
#include <qabstracteventdispatcher.h>
#include <qcoreapplication.h>
#include <qmetaobject.h>
+#include <qscopeguard.h>
#include <qstringlist.h>
#include <qthread.h>
#include <qurl.h>
@@ -53,6 +57,15 @@
#ifdef Q_OS_UNIX
# include <unistd.h>
+# include <netdb.h>
+# include <netinet/in.h>
+# if defined(AI_ADDRCONFIG)
+# define Q_ADDRCONFIG AI_ADDRCONFIG
+# endif
+#elif defined Q_OS_WIN
+# include <ws2tcpip.h>
+
+# define QT_SOCKLEN_T int
#endif
QT_BEGIN_NAMESPACE
@@ -64,8 +77,8 @@ Q_GLOBAL_STATIC(QHostInfoLookupManager, theHostInfoLookupManager)
namespace {
struct ToBeLookedUpEquals {
typedef bool result_type;
- explicit ToBeLookedUpEquals(const QString &toBeLookedUp) Q_DECL_NOTHROW : m_toBeLookedUp(toBeLookedUp) {}
- result_type operator()(QHostInfoRunnable* lookup) const Q_DECL_NOTHROW
+ explicit ToBeLookedUpEquals(const QString &toBeLookedUp) noexcept : m_toBeLookedUp(toBeLookedUp) {}
+ result_type operator()(QHostInfoRunnable* lookup) const noexcept
{
return m_toBeLookedUp == lookup->toBeLookedUp;
}
@@ -73,13 +86,6 @@ private:
QString m_toBeLookedUp;
};
-// ### C++11: remove once we can use std::any_of()
-template<class InputIt, class UnaryPredicate>
-bool any_of(InputIt first, InputIt last, UnaryPredicate p)
-{
- return std::find_if(first, last, p) != last;
-}
-
template <typename InputIt, typename OutputIt1, typename OutputIt2, typename UnaryPredicate>
std::pair<OutputIt1, OutputIt2> separate_if(InputIt first, InputIt last, OutputIt1 dest1, OutputIt2 dest2, UnaryPredicate p)
{
@@ -96,16 +102,6 @@ std::pair<OutputIt1, OutputIt2> separate_if(InputIt first, InputIt last, OutputI
return std::make_pair(dest1, dest2);
}
-int get_signal_index()
-{
- static auto senderMetaObject = &QHostInfoResult::staticMetaObject;
- static auto signal = &QHostInfoResult::resultsReady;
- int signal_index = -1;
- void *args[] = { &signal_index, &signal };
- senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
- return signal_index + QMetaObjectPrivate::signalOffset(senderMetaObject);
-}
-
}
/*
@@ -123,38 +119,59 @@ void QHostInfoResult::postResultsReady(const QHostInfo &info)
{
// queued connection will take care of dispatching to right thread
if (!slotObj) {
- emitResultsReady(info);
+ emit resultsReady(info);
return;
}
- static const int signal_index = get_signal_index();
-
// we used to have a context object, but it's already destroyed
if (withContextObject && !receiver)
return;
- /* QHostInfoResult c'tor moves the result object to the thread of receiver.
- If we don't have a receiver, then the result object will not live in a
- thread that runs an event loop - so move it to this' thread, which is the thread
- that initiated the lookup, and required to have a running event loop. */
- auto result = new QHostInfoResult(receiver, slotObj);
- if (!receiver)
- result->moveToThread(thread());
+ static const int signal_index = []() -> int {
+ auto senderMetaObject = &QHostInfoResult::staticMetaObject;
+ auto signal = &QHostInfoResult::resultsReady;
+ int signal_index = -1;
+ void *args[] = { &signal_index, &signal };
+ senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
+ return signal_index + QMetaObjectPrivate::signalOffset(senderMetaObject);
+ }();
+
+ // a long-living version of this
+ auto result = new QHostInfoResult(this);
Q_CHECK_PTR(result);
+
const int nargs = 2;
- auto types = reinterpret_cast<int *>(malloc(nargs * sizeof(int)));
- Q_CHECK_PTR(types);
+ auto metaCallEvent = new QMetaCallEvent(slotObj, nullptr, signal_index, nargs);
+ Q_CHECK_PTR(metaCallEvent);
+ void **args = metaCallEvent->args();
+ int *types = metaCallEvent->types();
types[0] = QMetaType::type("void");
types[1] = QMetaType::type("QHostInfo");
- auto args = reinterpret_cast<void **>(malloc(nargs * sizeof(void *)));
- Q_CHECK_PTR(args);
- args[0] = 0;
+ args[0] = nullptr;
args[1] = QMetaType::create(types[1], &info);
Q_CHECK_PTR(args[1]);
- auto metaCallEvent = new QMetaCallEvent(slotObj, nullptr, signal_index, nargs, types, args);
- Q_CHECK_PTR(metaCallEvent);
qApp->postEvent(result, metaCallEvent);
}
+/*
+ Receives the event posted by postResultsReady, and calls the functor.
+*/
+bool QHostInfoResult::event(QEvent *event)
+{
+ if (event->type() == QEvent::MetaCall) {
+ Q_ASSERT(slotObj);
+ auto metaCallEvent = static_cast<QMetaCallEvent *>(event);
+ auto args = metaCallEvent->args();
+ // we didn't have a context object, or it's still alive
+ if (!withContextObject || receiver)
+ slotObj->call(const_cast<QObject*>(receiver.data()), args);
+ slotObj->destroyIfLastRef();
+
+ deleteLater();
+ return true;
+ }
+ return QObject::event(event);
+}
+
/*!
\class QHostInfo
\brief The QHostInfo class provides static functions for host name lookups.
@@ -249,64 +266,9 @@ static int nextId()
\sa abortHostLookup(), addresses(), error(), fromName()
*/
-int QHostInfo::lookupHost(const QString &name, QObject *receiver,
- const char *member)
+int QHostInfo::lookupHost(const QString &name, QObject *receiver, const char *member)
{
-#if defined QHOSTINFO_DEBUG
- qDebug("QHostInfo::lookupHost(\"%s\", %p, %s)",
- name.toLatin1().constData(), receiver, member ? member + 1 : 0);
-#endif
-
- if (!QAbstractEventDispatcher::instance(QThread::currentThread())) {
- qWarning("QHostInfo::lookupHost() called with no event dispatcher");
- return -1;
- }
-
- qRegisterMetaType<QHostInfo>();
-
- int id = nextId(); // generate unique ID
-
- if (name.isEmpty()) {
- if (!receiver)
- return -1;
-
- QHostInfo hostInfo(id);
- hostInfo.setError(QHostInfo::HostNotFound);
- hostInfo.setErrorString(QCoreApplication::translate("QHostInfo", "No host name given"));
- QScopedPointer<QHostInfoResult> result(new QHostInfoResult);
- QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)),
- receiver, member, Qt::QueuedConnection);
- result.data()->emitResultsReady(hostInfo);
- return id;
- }
-
- QHostInfoLookupManager *manager = theHostInfoLookupManager();
-
- if (manager) {
- // the application is still alive
- if (manager->cache.isEnabled()) {
- // check cache first
- bool valid = false;
- QHostInfo info = manager->cache.get(name, &valid);
- if (valid) {
- if (!receiver)
- return -1;
-
- info.setLookupId(id);
- QHostInfoResult result;
- QObject::connect(&result, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection);
- result.emitResultsReady(info);
- return id;
- }
- }
-
- // cache is not enabled or it was not in the cache, do normal lookup
- QHostInfoRunnable* runnable = new QHostInfoRunnable(name, id);
- if (receiver)
- QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection);
- manager->scheduleLookup(runnable);
- }
- return id;
+ return QHostInfoPrivate::lookupHostImpl(name, receiver, nullptr, member);
}
/*!
@@ -416,7 +378,7 @@ QHostInfo QHostInfo::fromName(const QString &name)
#endif
QHostInfo hostInfo = QHostInfoAgent::fromName(name);
- QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager();
+ QHostInfoLookupManager* manager = theHostInfoLookupManager();
manager->cache.put(name, hostInfo);
return hostInfo;
}
@@ -429,7 +391,7 @@ QHostInfo QHostInfoPrivate::fromName(const QString &name, QSharedPointer<QNetwor
#endif
QHostInfo hostInfo = QHostInfoAgent::fromName(name, session);
- QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager();
+ QHostInfoLookupManager* manager = theHostInfoLookupManager();
manager->cache.put(name, hostInfo);
return hostInfo;
}
@@ -442,6 +404,162 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName, QSharedPointer<QNetw
}
#endif
+QHostInfo QHostInfoAgent::reverseLookup(const QHostAddress &address)
+{
+ QHostInfo results;
+ // Reverse lookup
+ sockaddr_in sa4;
+ sockaddr_in6 sa6;
+ sockaddr *sa = 0;
+ QT_SOCKLEN_T saSize;
+ if (address.protocol() == QAbstractSocket::IPv4Protocol) {
+ sa = reinterpret_cast<sockaddr *>(&sa4);
+ saSize = sizeof(sa4);
+ memset(&sa4, 0, sizeof(sa4));
+ sa4.sin_family = AF_INET;
+ sa4.sin_addr.s_addr = htonl(address.toIPv4Address());
+ } else {
+ sa = reinterpret_cast<sockaddr *>(&sa6);
+ saSize = sizeof(sa6);
+ memset(&sa6, 0, sizeof(sa6));
+ sa6.sin6_family = AF_INET6;
+ memcpy(&sa6.sin6_addr, address.toIPv6Address().c, sizeof(sa6.sin6_addr));
+ }
+
+ char hbuf[NI_MAXHOST];
+ if (sa && getnameinfo(sa, saSize, hbuf, sizeof(hbuf), nullptr, 0, 0) == 0)
+ results.setHostName(QString::fromLatin1(hbuf));
+
+ if (results.hostName().isEmpty())
+ results.setHostName(address.toString());
+ results.setAddresses(QList<QHostAddress>() << address);
+
+ return results;
+}
+
+/*
+ Call getaddrinfo, and returns the results as QHostInfo::addresses
+*/
+QHostInfo QHostInfoAgent::lookup(const QString &hostName)
+{
+ QHostInfo results;
+
+ // IDN support
+ QByteArray aceHostname = QUrl::toAce(hostName);
+ results.setHostName(hostName);
+ if (aceHostname.isEmpty()) {
+ results.setError(QHostInfo::HostNotFound);
+ results.setErrorString(hostName.isEmpty() ?
+ QCoreApplication::translate("QHostInfoAgent", "No host name given") :
+ QCoreApplication::translate("QHostInfoAgent", "Invalid hostname"));
+ return results;
+ }
+
+ addrinfo *res = 0;
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+#ifdef Q_ADDRCONFIG
+ hints.ai_flags = Q_ADDRCONFIG;
+#endif
+
+ int result = getaddrinfo(aceHostname.constData(), nullptr, &hints, &res);
+# ifdef Q_ADDRCONFIG
+ if (result == EAI_BADFLAGS) {
+ // if the lookup failed with AI_ADDRCONFIG set, try again without it
+ hints.ai_flags = 0;
+ result = getaddrinfo(aceHostname.constData(), nullptr, &hints, &res);
+ }
+# endif
+
+ if (result == 0) {
+ addrinfo *node = res;
+ QList<QHostAddress> addresses;
+ while (node) {
+#ifdef QHOSTINFO_DEBUG
+ qDebug() << "getaddrinfo node: flags:" << node->ai_flags << "family:" << node->ai_family
+ << "ai_socktype:" << node->ai_socktype << "ai_protocol:" << node->ai_protocol
+ << "ai_addrlen:" << node->ai_addrlen;
+#endif
+ switch (node->ai_family) {
+ case AF_INET: {
+ QHostAddress addr;
+ addr.setAddress(ntohl(((sockaddr_in *) node->ai_addr)->sin_addr.s_addr));
+ if (!addresses.contains(addr))
+ addresses.append(addr);
+ break;
+ }
+ case AF_INET6: {
+ QHostAddress addr;
+ sockaddr_in6 *sa6 = (sockaddr_in6 *) node->ai_addr;
+ addr.setAddress(sa6->sin6_addr.s6_addr);
+ if (sa6->sin6_scope_id)
+ addr.setScopeId(QString::number(sa6->sin6_scope_id));
+ if (!addresses.contains(addr))
+ addresses.append(addr);
+ break;
+ }
+ default:
+ results.setError(QHostInfo::UnknownError);
+ results.setErrorString(QCoreApplication::translate("QHostInfoAgent", "Unknown address type"));
+ }
+ node = node->ai_next;
+ }
+ if (addresses.isEmpty()) {
+ // Reached the end of the list, but no addresses were found; this
+ // means the list contains one or more unknown address types.
+ results.setError(QHostInfo::UnknownError);
+ results.setErrorString(QCoreApplication::translate("QHostInfoAgent", "Unknown address type"));
+ }
+
+ results.setAddresses(addresses);
+ freeaddrinfo(res);
+ } else {
+ switch (result) {
+#ifdef Q_OS_WIN
+ case WSAHOST_NOT_FOUND: //authoritative not found
+ case WSATRY_AGAIN: //non authoritative not found
+ case WSANO_DATA: //valid name, no associated address
+#else
+ case EAI_NONAME:
+ case EAI_FAIL:
+# ifdef EAI_NODATA // EAI_NODATA is deprecated in RFC 3493
+ case EAI_NODATA:
+# endif
+#endif
+ results.setError(QHostInfo::HostNotFound);
+ results.setErrorString(QCoreApplication::translate("QHostInfoAgent", "Host not found"));
+ break;
+ default:
+ results.setError(QHostInfo::UnknownError);
+#ifdef Q_OS_WIN
+ results.setErrorString(QString::fromWCharArray(gai_strerror(result)));
+#else
+ results.setErrorString(QString::fromLocal8Bit(gai_strerror(result)));
+#endif
+ break;
+ }
+ }
+
+#if defined(QHOSTINFO_DEBUG)
+ if (results.error() != QHostInfo::NoError) {
+ qDebug("QHostInfoAgent::fromName(): error #%d %s",
+ h_errno, results.errorString().toLatin1().constData());
+ } else {
+ QString tmp;
+ QList<QHostAddress> addresses = results.addresses();
+ for (int i = 0; i < addresses.count(); ++i) {
+ if (i != 0) tmp += QLatin1String(", ");
+ tmp += addresses.at(i).toString();
+ }
+ qDebug("QHostInfoAgent::fromName(): found %i entries for \"%s\": {%s}",
+ addresses.count(), aceHostname.constData(),
+ tmp.toLatin1().constData());
+ }
+#endif
+
+ return results;
+}
/*!
\enum QHostInfo::HostInfoError
@@ -462,8 +580,9 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName, QSharedPointer<QNetw
\sa lookupId()
*/
QHostInfo::QHostInfo(int id)
- : d(new QHostInfoPrivate)
+ : d_ptr(new QHostInfoPrivate)
{
+ Q_D(QHostInfo);
d->lookupId = id;
}
@@ -471,17 +590,32 @@ QHostInfo::QHostInfo(int id)
Constructs a copy of \a other.
*/
QHostInfo::QHostInfo(const QHostInfo &other)
- : d(new QHostInfoPrivate(*other.d.data()))
+ : d_ptr(new QHostInfoPrivate(*other.d_ptr))
{
}
/*!
+ \fn QHostInfo(QHostInfo &&other)
+
+ Move-constructs a new QHostInfo from \a other.
+
+ \note The moved-from object \a other is placed in a
+ partially-formed state, in which the only valid operations are
+ destruction and assignment of a new value.
+
+ \since 5.14
+*/
+
+/*!
Assigns the data of the \a other object to this host info object,
and returns a reference to it.
*/
QHostInfo &QHostInfo::operator=(const QHostInfo &other)
{
- *d.data() = *other.d.data();
+ if (d_ptr)
+ *d_ptr = *other.d_ptr;
+ else
+ d_ptr = new QHostInfoPrivate(*other.d_ptr);
return *this;
}
@@ -490,6 +624,7 @@ QHostInfo &QHostInfo::operator=(const QHostInfo &other)
*/
QHostInfo::~QHostInfo()
{
+ delete d_ptr;
}
/*!
@@ -504,6 +639,7 @@ QHostInfo::~QHostInfo()
*/
QList<QHostAddress> QHostInfo::addresses() const
{
+ Q_D(const QHostInfo);
return d->addrs;
}
@@ -514,6 +650,7 @@ QList<QHostAddress> QHostInfo::addresses() const
*/
void QHostInfo::setAddresses(const QList<QHostAddress> &addresses)
{
+ Q_D(QHostInfo);
d->addrs = addresses;
}
@@ -524,6 +661,7 @@ void QHostInfo::setAddresses(const QList<QHostAddress> &addresses)
*/
QString QHostInfo::hostName() const
{
+ Q_D(const QHostInfo);
return d->hostName;
}
@@ -534,6 +672,7 @@ QString QHostInfo::hostName() const
*/
void QHostInfo::setHostName(const QString &hostName)
{
+ Q_D(QHostInfo);
d->hostName = hostName;
}
@@ -545,6 +684,7 @@ void QHostInfo::setHostName(const QString &hostName)
*/
QHostInfo::HostInfoError QHostInfo::error() const
{
+ Q_D(const QHostInfo);
return d->err;
}
@@ -555,6 +695,7 @@ QHostInfo::HostInfoError QHostInfo::error() const
*/
void QHostInfo::setError(HostInfoError error)
{
+ Q_D(QHostInfo);
d->err = error;
}
@@ -565,6 +706,7 @@ void QHostInfo::setError(HostInfoError error)
*/
int QHostInfo::lookupId() const
{
+ Q_D(const QHostInfo);
return d->lookupId;
}
@@ -575,6 +717,7 @@ int QHostInfo::lookupId() const
*/
void QHostInfo::setLookupId(int id)
{
+ Q_D(QHostInfo);
d->lookupId = id;
}
@@ -586,6 +729,7 @@ void QHostInfo::setLookupId(int id)
*/
QString QHostInfo::errorString() const
{
+ Q_D(const QHostInfo);
return d->errorStr;
}
@@ -597,6 +741,7 @@ QString QHostInfo::errorString() const
*/
void QHostInfo::setErrorString(const QString &str)
{
+ Q_D(QHostInfo);
d->errorStr = str;
}
@@ -631,14 +776,32 @@ QString QHostInfo::localHostName()
\sa hostName()
*/
+// ### Qt 6 merge with function below
int QHostInfo::lookupHostImpl(const QString &name,
const QObject *receiver,
QtPrivate::QSlotObjectBase *slotObj)
{
+ return QHostInfoPrivate::lookupHostImpl(name, receiver, slotObj, nullptr);
+}
+/*
+ Called by the various lookupHost overloads to perform the lookup.
+
+ Signals either the functor encapuslated in the \a slotObj in the context
+ of \a receiver, or the \a member slot of the \a receiver.
+
+ \a receiver might be the nullptr, but only if a \a slotObj is provided.
+*/
+int QHostInfoPrivate::lookupHostImpl(const QString &name,
+ const QObject *receiver,
+ QtPrivate::QSlotObjectBase *slotObj,
+ const char *member)
+{
#if defined QHOSTINFO_DEBUG
- qDebug("QHostInfo::lookupHost(\"%s\", %p, %p)",
- name.toLatin1().constData(), receiver, slotObj);
+ qDebug("QHostInfoPrivate::lookupHostImpl(\"%s\", %p, %p, %s)",
+ name.toLatin1().constData(), receiver, slotObj, member ? member + 1 : 0);
#endif
+ Q_ASSERT(!member != !slotObj); // one of these must be set, but not both
+ Q_ASSERT(receiver || slotObj);
if (!QAbstractEventDispatcher::instance(QThread::currentThread())) {
qWarning("QHostInfo::lookupHost() called with no event dispatcher");
@@ -653,8 +816,13 @@ int QHostInfo::lookupHostImpl(const QString &name,
QHostInfo hostInfo(id);
hostInfo.setError(QHostInfo::HostNotFound);
hostInfo.setErrorString(QCoreApplication::translate("QHostInfo", "No host name given"));
+
QHostInfoResult result(receiver, slotObj);
+ if (receiver && member)
+ QObject::connect(&result, SIGNAL(resultsReady(QHostInfo)),
+ receiver, member, Qt::QueuedConnection);
result.postResultsReady(hostInfo);
+
return id;
}
@@ -669,23 +837,24 @@ int QHostInfo::lookupHostImpl(const QString &name,
if (valid) {
info.setLookupId(id);
QHostInfoResult result(receiver, slotObj);
+ if (receiver && member)
+ QObject::connect(&result, SIGNAL(resultsReady(QHostInfo)),
+ receiver, member, Qt::QueuedConnection);
result.postResultsReady(info);
return id;
}
}
// cache is not enabled or it was not in the cache, do normal lookup
- QHostInfoRunnable* runnable = new QHostInfoRunnable(name, id, receiver, slotObj);
+ QHostInfoRunnable *runnable = new QHostInfoRunnable(name, id, receiver, slotObj);
+ if (receiver && member)
+ QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)),
+ receiver, member, Qt::QueuedConnection);
manager->scheduleLookup(runnable);
}
return id;
}
-QHostInfoRunnable::QHostInfoRunnable(const QString &hn, int i) : toBeLookedUp(hn), id(i)
-{
- setAutoDelete(true);
-}
-
QHostInfoRunnable::QHostInfoRunnable(const QString &hn, int i, const QObject *receiver,
QtPrivate::QSlotObjectBase *slotObj) :
toBeLookedUp(hn), id(i), resultEmitter(receiver, slotObj)
@@ -697,11 +866,10 @@ QHostInfoRunnable::QHostInfoRunnable(const QString &hn, int i, const QObject *re
void QHostInfoRunnable::run()
{
QHostInfoLookupManager *manager = theHostInfoLookupManager();
+ const auto sg = qScopeGuard([&] { manager->lookupFinished(this); });
// check aborted
- if (manager->wasAborted(id)) {
- manager->lookupFinished(this);
+ if (manager->wasAborted(id))
return;
- }
QHostInfo hostInfo;
@@ -723,10 +891,8 @@ void QHostInfoRunnable::run()
}
// check aborted again
- if (manager->wasAborted(id)) {
- manager->lookupFinished(this);
+ if (manager->wasAborted(id))
return;
- }
// signal emission
hostInfo.setLookupId(id);
@@ -750,16 +916,15 @@ void QHostInfoRunnable::run()
}
#endif
- manager->lookupFinished(this);
-
// thread goes back to QThreadPool
}
-QHostInfoLookupManager::QHostInfoLookupManager() : mutex(QMutex::Recursive), wasDeleted(false)
+QHostInfoLookupManager::QHostInfoLookupManager() : wasDeleted(false)
{
- moveToThread(QCoreApplicationPrivate::mainThread());
#if QT_CONFIG(thread)
- connect(QCoreApplication::instance(), SIGNAL(destroyed()), SLOT(waitForThreadPoolDone()), Qt::DirectConnection);
+ QObject::connect(QCoreApplication::instance(), &QObject::destroyed,
+ &threadPool, [&](QObject *) { threadPool.waitForDone(); },
+ Qt::DirectConnection);
threadPool.setMaxThreadCount(20); // do up to 20 DNS lookups in parallel
#endif
}
@@ -794,10 +959,9 @@ void QHostInfoLookupManager::clear()
cache.clear();
}
-void QHostInfoLookupManager::work()
+// assumes mutex is locked by caller
+void QHostInfoLookupManager::rescheduleWithMutexHeld()
{
- QMutexLocker locker(&mutex);
-
if (wasDeleted)
return;
@@ -816,7 +980,7 @@ void QHostInfoLookupManager::work()
#if QT_CONFIG(thread)
auto isAlreadyRunning = [this](QHostInfoRunnable *lookup) {
- return any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp));
+ return std::any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp));
};
// Transfer any postponed lookups that aren't currently running to the scheduled list, keeping already-running lookups:
@@ -862,7 +1026,7 @@ void QHostInfoLookupManager::scheduleLookup(QHostInfoRunnable *r)
return;
scheduledLookups.enqueue(r);
- work();
+ rescheduleWithMutexHeld();
}
// called by QHostInfo
@@ -918,7 +1082,7 @@ void QHostInfoLookupManager::lookupFinished(QHostInfoRunnable *r)
currentLookups.removeOne(r);
#endif
finishedLookups.append(r);
- work();
+ rescheduleWithMutexHeld();
}
// This function returns immediately when we had a result in the cache, else it will later emit a signal
@@ -928,7 +1092,7 @@ QHostInfo qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char
*id = -1;
// check cache
- QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager();
+ QHostInfoLookupManager* manager = theHostInfoLookupManager();
if (manager && manager->cache.isEnabled()) {
QHostInfo info = manager->cache.get(name, valid);
if (*valid) {
@@ -937,7 +1101,7 @@ QHostInfo qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char
}
// was not in cache, trigger lookup
- *id = QHostInfo::lookupHost(name, receiver, member);
+ *id = QHostInfoPrivate::lookupHostImpl(name, receiver, nullptr, member);
// return empty response, valid==false
return QHostInfo();
@@ -945,7 +1109,7 @@ QHostInfo qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char
void qt_qhostinfo_clear_cache()
{
- QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager();
+ QHostInfoLookupManager* manager = theHostInfoLookupManager();
if (manager) {
manager->clear();
}
@@ -954,7 +1118,7 @@ void qt_qhostinfo_clear_cache()
#ifdef QT_BUILD_INTERNAL
void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e)
{
- QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager();
+ QHostInfoLookupManager* manager = theHostInfoLookupManager();
if (manager) {
manager->cache.setEnabled(e);
}
@@ -962,7 +1126,7 @@ void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e)
void qt_qhostinfo_cache_inject(const QString &hostname, const QHostInfo &resolution)
{
- QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager();
+ QHostInfoLookupManager* manager = theHostInfoLookupManager();
if (!manager || !manager->cache.isEnabled())
return;
@@ -1018,9 +1182,4 @@ void QHostInfoCache::clear()
cache.clear();
}
-QAbstractHostInfoLookupManager* QAbstractHostInfoLookupManager::globalInstance()
-{
- return theHostInfoLookupManager();
-}
-
QT_END_NAMESPACE