Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qhostinfo.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4//#define QHOSTINFO_DEBUG
5
6#include "qhostinfo.h"
7#include "qhostinfo_p.h"
8#include <qplatformdefs.h>
9
10#include "QtCore/qapplicationstatic.h"
11#include "QtCore/qscopedpointer.h"
13#include <qcoreapplication.h>
14#include <qmetaobject.h>
15#include <qscopeguard.h>
16#include <qstringlist.h>
17#include <qthread.h>
18#include <qurl.h>
19
20#include <algorithm>
21
22#ifdef Q_OS_UNIX
23# include <unistd.h>
24# include <netdb.h>
25# include <netinet/in.h>
26# if defined(AI_ADDRCONFIG) && !defined(Q_OS_WASM)
27# define Q_ADDRCONFIG AI_ADDRCONFIG
28# endif
29#elif defined Q_OS_WIN
30# include <ws2tcpip.h>
31
32# define QT_SOCKLEN_T int
33#endif
34
36
37using namespace Qt::StringLiterals;
38
39//#define QHOSTINFO_DEBUG
40
42
43namespace {
44struct ToBeLookedUpEquals {
45 typedef bool result_type;
46 explicit ToBeLookedUpEquals(const QString &toBeLookedUp) noexcept : m_toBeLookedUp(toBeLookedUp) {}
47 result_type operator()(QHostInfoRunnable* lookup) const noexcept
48 {
49 return m_toBeLookedUp == lookup->toBeLookedUp;
50 }
51private:
52 QString m_toBeLookedUp;
53};
54
55template <typename InputIt, typename OutputIt1, typename OutputIt2, typename UnaryPredicate>
56std::pair<OutputIt1, OutputIt2> separate_if(InputIt first, InputIt last, OutputIt1 dest1, OutputIt2 dest2, UnaryPredicate p)
57{
58 while (first != last) {
59 if (p(*first)) {
60 *dest1 = *first;
61 ++dest1;
62 } else {
63 *dest2 = *first;
64 ++dest2;
65 }
66 ++first;
67 }
68 return std::make_pair(dest1, dest2);
69}
70
71Q_APPLICATION_STATIC(QHostInfoLookupManager, theHostInfoLookupManager)
72
73}
74
75/*
76 The calling thread is likely the one that executes the lookup via
77 QHostInfoRunnable. Unless we operate with a queued connection already,
78 posts the QHostInfo to a dedicated QHostInfoResult object that lives in
79 the same thread as the user-provided receiver, or (if there is none) in
80 the thread that made the call to lookupHost. That QHostInfoResult object
81 then calls the user code in the correct thread.
82
83 The 'result' object deletes itself (via deleteLater) when the metacall
84 event is received.
85*/
87{
88 // queued connection will take care of dispatching to right thread
89 if (!slotObj) {
91 return;
92 }
93 // we used to have a context object, but it's already destroyed
94 if (withContextObject && !receiver)
95 return;
96
97 static const int signal_index = []() -> int {
98 auto senderMetaObject = &QHostInfoResult::staticMetaObject;
100 int signal_index = -1;
101 void *args[] = { &signal_index, &signal };
102 senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
103 return signal_index + QMetaObjectPrivate::signalOffset(senderMetaObject);
104 }();
105
106 // a long-living version of this
107 auto result = new QHostInfoResult(this);
109
110 auto metaCallEvent = QMetaCallEvent::create(slotObj, nullptr, signal_index, info);
111 Q_CHECK_PTR(metaCallEvent);
112 qApp->postEvent(result, metaCallEvent);
113}
114
115/*
116 Receives the event posted by postResultsReady, and calls the functor.
117*/
119{
120 if (event->type() == QEvent::MetaCall) {
121 Q_ASSERT(slotObj);
122 auto metaCallEvent = static_cast<QMetaCallEvent *>(event);
123 auto args = metaCallEvent->args();
124 // we didn't have a context object, or it's still alive
125 if (!withContextObject || receiver)
126 slotObj->call(const_cast<QObject*>(receiver.data()), args);
127 slotObj->destroyIfLastRef();
128
129 deleteLater();
130 return true;
131 }
132 return QObject::event(event);
133}
134
193static int nextId()
194{
195 Q_CONSTINIT static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(0);
196 return 1 + counter.fetchAndAddRelaxed(1);
197}
198
228int QHostInfo::lookupHost(const QString &name, QObject *receiver, const char *member)
229{
230 return QHostInfo::lookupHostImpl(name, receiver, nullptr, member);
231}
232
316{
317 theHostInfoLookupManager()->abortLookup(id);
318}
319
334{
335#if defined QHOSTINFO_DEBUG
336 qDebug("QHostInfo::fromName(\"%s\")",name.toLatin1().constData());
337#endif
338
339#ifdef Q_OS_WASM
341#else
343 QHostInfoLookupManager* manager = theHostInfoLookupManager();
344 manager->cache.put(name, hostInfo);
345 return hostInfo;
346#endif
347}
348
349
351{
353 // Reverse lookup
354 sockaddr_in sa4;
355 sockaddr_in6 sa6;
356 sockaddr *sa = nullptr;
357 QT_SOCKLEN_T saSize;
358 if (address.protocol() == QAbstractSocket::IPv4Protocol) {
359 sa = reinterpret_cast<sockaddr *>(&sa4);
360 saSize = sizeof(sa4);
361 memset(&sa4, 0, sizeof(sa4));
362 sa4.sin_family = AF_INET;
363 sa4.sin_addr.s_addr = htonl(address.toIPv4Address());
364 } else {
365 sa = reinterpret_cast<sockaddr *>(&sa6);
366 saSize = sizeof(sa6);
367 memset(&sa6, 0, sizeof(sa6));
368 sa6.sin6_family = AF_INET6;
369 memcpy(&sa6.sin6_addr, address.toIPv6Address().c, sizeof(sa6.sin6_addr));
370 }
371
372 char hbuf[NI_MAXHOST];
373 if (sa && getnameinfo(sa, saSize, hbuf, sizeof(hbuf), nullptr, 0, 0) == 0)
374 results.setHostName(QString::fromLatin1(hbuf));
375
376 if (results.hostName().isEmpty())
377 results.setHostName(address.toString());
378 results.setAddresses(QList<QHostAddress>() << address);
379
380 return results;
381}
382
383/*
384 Call getaddrinfo, and returns the results as QHostInfo::addresses
385*/
387{
389
390 // IDN support
391 QByteArray aceHostname = QUrl::toAce(hostName);
392 results.setHostName(hostName);
393 if (aceHostname.isEmpty()) {
395 results.setErrorString(hostName.isEmpty() ?
396 QCoreApplication::translate("QHostInfoAgent", "No host name given") :
397 QCoreApplication::translate("QHostInfoAgent", "Invalid hostname"));
398 return results;
399 }
400
401 addrinfo *res = nullptr;
402 struct addrinfo hints;
403 memset(&hints, 0, sizeof(hints));
404 hints.ai_family = PF_UNSPEC;
405#ifdef Q_ADDRCONFIG
406 hints.ai_flags = Q_ADDRCONFIG;
407#endif
408
409 int result = getaddrinfo(aceHostname.constData(), nullptr, &hints, &res);
410# ifdef Q_ADDRCONFIG
411 if (result == EAI_BADFLAGS) {
412 // if the lookup failed with AI_ADDRCONFIG set, try again without it
413 hints.ai_flags = 0;
414 result = getaddrinfo(aceHostname.constData(), nullptr, &hints, &res);
415 }
416# endif
417
418 if (result == 0) {
419 addrinfo *node = res;
420 QList<QHostAddress> addresses;
421 while (node) {
422#ifdef QHOSTINFO_DEBUG
423 qDebug() << "getaddrinfo node: flags:" << node->ai_flags << "family:" << node->ai_family
424 << "ai_socktype:" << node->ai_socktype << "ai_protocol:" << node->ai_protocol
425 << "ai_addrlen:" << node->ai_addrlen;
426#endif
427 switch (node->ai_family) {
428 case AF_INET: {
430 addr.setAddress(ntohl(((sockaddr_in *) node->ai_addr)->sin_addr.s_addr));
431 if (!addresses.contains(addr))
432 addresses.append(addr);
433 break;
434 }
435 case AF_INET6: {
437 sockaddr_in6 *sa6 = (sockaddr_in6 *) node->ai_addr;
438 addr.setAddress(sa6->sin6_addr.s6_addr);
439 if (sa6->sin6_scope_id)
440 addr.setScopeId(QString::number(sa6->sin6_scope_id));
441 if (!addresses.contains(addr))
442 addresses.append(addr);
443 break;
444 }
445 default:
447 results.setErrorString(QCoreApplication::translate("QHostInfoAgent", "Unknown address type"));
448 }
449 node = node->ai_next;
450 }
451 if (addresses.isEmpty()) {
452 // Reached the end of the list, but no addresses were found; this
453 // means the list contains one or more unknown address types.
455 results.setErrorString(QCoreApplication::translate("QHostInfoAgent", "Unknown address type"));
456 }
457
458 results.setAddresses(addresses);
459 freeaddrinfo(res);
460 } else {
461 switch (result) {
462#ifdef Q_OS_WIN
463 case WSAHOST_NOT_FOUND: //authoritative not found
464 case WSATRY_AGAIN: //non authoritative not found
465 case WSANO_DATA: //valid name, no associated address
466#else
467 case EAI_NONAME:
468 case EAI_FAIL:
469# ifdef EAI_NODATA // EAI_NODATA is deprecated in RFC 3493
470 case EAI_NODATA:
471# endif
472#endif
474 results.setErrorString(QCoreApplication::translate("QHostInfoAgent", "Host not found"));
475 break;
476 default:
478#ifdef Q_OS_WIN
479 results.setErrorString(QString::fromWCharArray(gai_strerror(result)));
480#else
481 results.setErrorString(QString::fromLocal8Bit(gai_strerror(result)));
482#endif
483 break;
484 }
485 }
486
487#if defined(QHOSTINFO_DEBUG)
488 if (results.error() != QHostInfo::NoError) {
489 qDebug("QHostInfoAgent::fromName(): error #%d %s",
490 h_errno, results.errorString().toLatin1().constData());
491 } else {
492 QString tmp;
493 QList<QHostAddress> addresses = results.addresses();
494 for (int i = 0; i < addresses.count(); ++i) {
495 if (i != 0) tmp += ", "_L1;
496 tmp += addresses.at(i).toString();
497 }
498 qDebug("QHostInfoAgent::fromName(): found %i entries for \"%s\": {%s}",
499 addresses.count(), aceHostname.constData(),
500 tmp.toLatin1().constData());
501 }
502#endif
503
504 return results;
505}
506
526 : d_ptr(new QHostInfoPrivate)
527{
528 Q_D(QHostInfo);
529 d->lookupId = id;
530}
531
536 : d_ptr(new QHostInfoPrivate(*other.d_ptr))
537{
538}
539
557{
558 if (this == &other)
559 return *this;
560
561 Q_ASSERT(d_ptr && other.d_ptr);
562 *d_ptr = *other.d_ptr;
563 return *this;
564}
565
570{
571 delete d_ptr;
572}
573
585{
586 Q_D(const QHostInfo);
587 return d->addrs;
588}
589
596{
597 Q_D(QHostInfo);
598 d->addrs = addresses;
599}
600
607{
608 Q_D(const QHostInfo);
609 return d->hostName;
610}
611
617void QHostInfo::setHostName(const QString &hostName)
618{
619 Q_D(QHostInfo);
620 d->hostName = hostName;
621}
622
630{
631 Q_D(const QHostInfo);
632 return d->err;
633}
634
641{
642 Q_D(QHostInfo);
643 d->err = error;
644}
645
652{
653 Q_D(const QHostInfo);
654 return d->lookupId;
655}
656
663{
664 Q_D(QHostInfo);
665 d->lookupId = id;
666}
667
675{
676 Q_D(const QHostInfo);
677 return d->errorStr;
678}
679
687{
688 Q_D(QHostInfo);
689 d->errorStr = str;
690}
691
708{
710}
711
732int QHostInfo::lookupHostImpl(const QString &name,
733 const QObject *receiver,
735 const char *member)
736{
737#if defined QHOSTINFO_DEBUG
738 qDebug("QHostInfo::lookupHostImpl(\"%s\", %p, %p, %s)",
739 name.toLatin1().constData(), receiver, slotObj, member ? member + 1 : 0);
740#endif
741 Q_ASSERT(!member != !slotObj); // one of these must be set, but not both
742 Q_ASSERT(receiver || slotObj);
743
745 qWarning("QHostInfo::lookupHost() called with no event dispatcher");
746 return -1;
747 }
748
749 qRegisterMetaType<QHostInfo>();
750
751 int id = nextId(); // generate unique ID
752
753 if (Q_UNLIKELY(name.isEmpty())) {
754 QHostInfo hostInfo(id);
755 hostInfo.setError(QHostInfo::HostNotFound);
756 hostInfo.setErrorString(QCoreApplication::translate("QHostInfo", "No host name given"));
757
758 QHostInfoResult result(receiver, slotObj);
759 if (receiver && member)
760 QObject::connect(&result, SIGNAL(resultsReady(QHostInfo)),
761 receiver, member, Qt::QueuedConnection);
762 result.postResultsReady(hostInfo);
763
764 return id;
765 }
766
767#ifdef Q_OS_WASM
768 // Resolve the host name directly without using a thread or cache,
769 // since Emscripten's host lookup is fast. Emscripten maintains an internal
770 // mapping of hosts and addresses for the purposes of WebSocket socket
771 // tunnelling, and does not perform an actual host lookup.
773 hostInfo.setLookupId(id);
774
775 QHostInfoResult result(receiver, slotObj);
776 if (receiver && member)
777 QObject::connect(&result, SIGNAL(resultsReady(QHostInfo)),
778 receiver, member, Qt::QueuedConnection);
779 result.postResultsReady(hostInfo);
780#else
781 QHostInfoLookupManager *manager = theHostInfoLookupManager();
782
783 if (Q_LIKELY(manager)) {
784 // the application is still alive
785 if (manager->cache.isEnabled()) {
786 // check cache first
787 bool valid = false;
788 QHostInfo info = manager->cache.get(name, &valid);
789 if (valid) {
790 info.setLookupId(id);
791 QHostInfoResult result(receiver, slotObj);
792 if (receiver && member)
793 QObject::connect(&result, SIGNAL(resultsReady(QHostInfo)),
794 receiver, member, Qt::QueuedConnection);
795 result.postResultsReady(info);
796 return id;
797 }
798 }
799
800 // cache is not enabled or it was not in the cache, do normal lookup
801 QHostInfoRunnable *runnable = new QHostInfoRunnable(name, id, receiver, slotObj);
802 if (receiver && member)
803 QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)),
804 receiver, member, Qt::QueuedConnection);
805 manager->scheduleLookup(runnable);
806 }
807#endif // Q_OS_WASM
808 return id;
809}
810
813 toBeLookedUp(hn), id(i), resultEmitter(receiver, slotObj)
814{
815 setAutoDelete(true);
816}
817
818// the QHostInfoLookupManager will at some point call this via a QThreadPool
820{
821 QHostInfoLookupManager *manager = theHostInfoLookupManager();
822 const auto sg = qScopeGuard([&] { manager->lookupFinished(this); });
823 // check aborted
824 if (manager->wasAborted(id))
825 return;
826
827 QHostInfo hostInfo;
828
829 // QHostInfo::lookupHost already checks the cache. However we need to check
830 // it here too because it might have been cache saved by another QHostInfoRunnable
831 // in the meanwhile while this QHostInfoRunnable was scheduled but not running
832 if (manager->cache.isEnabled()) {
833 // check the cache first
834 bool valid = false;
835 hostInfo = manager->cache.get(toBeLookedUp, &valid);
836 if (!valid) {
837 // not in cache, we need to do the lookup and store the result in the cache
839 manager->cache.put(toBeLookedUp, hostInfo);
840 }
841 } else {
842 // cache is not enabled, just do the lookup and continue
844 }
845
846 // check aborted again
847 if (manager->wasAborted(id))
848 return;
849
850 // signal emission
851 hostInfo.setLookupId(id);
853
854#if QT_CONFIG(thread)
855 // now also iterate through the postponed ones
856 {
857 QMutexLocker locker(&manager->mutex);
858 const auto partitionBegin = std::stable_partition(manager->postponedLookups.rbegin(), manager->postponedLookups.rend(),
859 ToBeLookedUpEquals(toBeLookedUp)).base();
860 const auto partitionEnd = manager->postponedLookups.end();
861 for (auto it = partitionBegin; it != partitionEnd; ++it) {
862 QHostInfoRunnable* postponed = *it;
863 // we can now emit
864 hostInfo.setLookupId(postponed->id);
865 postponed->resultEmitter.postResultsReady(hostInfo);
866 delete postponed;
867 }
868 manager->postponedLookups.erase(partitionBegin, partitionEnd);
869 }
870
871#endif
872 // thread goes back to QThreadPool
873}
874
876{
877#if QT_CONFIG(thread)
879 &threadPool, [&](QObject *) { threadPool.waitForDone(); },
881 threadPool.setMaxThreadCount(20); // do up to 20 DNS lookups in parallel
882#endif
883}
884
886{
887 QMutexLocker locker(&mutex);
888 wasDeleted = true;
889 locker.unlock();
890
891 // don't qDeleteAll currentLookups, the QThreadPool has ownership
892 clear();
893}
894
896{
897 {
898 QMutexLocker locker(&mutex);
901#if QT_CONFIG(thread)
902 qDeleteAll(postponedLookups);
903 postponedLookups.clear();
904#endif
907 }
908
909#if QT_CONFIG(thread)
910 threadPool.waitForDone();
911#endif
912 cache.clear();
913}
914
915// assumes mutex is locked by caller
916void QHostInfoLookupManager::rescheduleWithMutexHeld()
917{
918 if (wasDeleted)
919 return;
920
921 // goals of this function:
922 // - launch new lookups via the thread pool
923 // - make sure only one lookup per host/IP is in progress
924
925 if (!finishedLookups.isEmpty()) {
926 // remove ID from aborted if it is in there
927 for (int i = 0; i < finishedLookups.size(); i++) {
929 }
930
932 }
933
934#if QT_CONFIG(thread)
935 auto isAlreadyRunning = [this](QHostInfoRunnable *lookup) {
936 return std::any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp));
937 };
938
939 // Transfer any postponed lookups that aren't currently running to the scheduled list, keeping already-running lookups:
940 postponedLookups.erase(separate_if(postponedLookups.begin(),
941 postponedLookups.end(),
942 postponedLookups.begin(),
943 std::front_inserter(scheduledLookups), // prepend! we want to finish it ASAP
944 isAlreadyRunning).first,
945 postponedLookups.end());
946
947 // Unschedule and postpone any that are currently running:
950 std::back_inserter(postponedLookups),
952 isAlreadyRunning).second,
954
955 const int availableThreads = threadPool.maxThreadCount() - currentLookups.size();
956 if (availableThreads > 0) {
957 int readyToStartCount = qMin(availableThreads, scheduledLookups.size());
958 auto it = scheduledLookups.begin();
959 while (readyToStartCount--) {
960 // runnable now running in new thread, track this in currentLookups
961 threadPool.start(*it);
962 currentLookups.push_back(std::move(*it));
963 ++it;
964 }
966 }
967#else
970#endif
971}
972
973// called by QHostInfo
975{
976 QMutexLocker locker(&this->mutex);
977
978 if (wasDeleted)
979 return;
980
982 rescheduleWithMutexHeld();
983}
984
985// called by QHostInfo
987{
988 QMutexLocker locker(&this->mutex);
989
990 if (wasDeleted)
991 return;
992
993#if QT_CONFIG(thread)
994 // is postponed? delete and return
995 for (int i = 0; i < postponedLookups.size(); i++) {
996 if (postponedLookups.at(i)->id == id) {
997 delete postponedLookups.takeAt(i);
998 return;
999 }
1000 }
1001#endif
1002
1003 // is scheduled? delete and return
1004 for (int i = 0; i < scheduledLookups.size(); i++) {
1005 if (scheduledLookups.at(i)->id == id) {
1006 delete scheduledLookups.takeAt(i);
1007 return;
1008 }
1009 }
1010
1011 if (!abortedLookups.contains(id))
1013}
1014
1015// called from QHostInfoRunnable
1017{
1018 QMutexLocker locker(&this->mutex);
1019
1020 if (wasDeleted)
1021 return true;
1022
1023 return abortedLookups.contains(id);
1024}
1025
1026// called from QHostInfoRunnable
1028{
1029 QMutexLocker locker(&this->mutex);
1030
1031 if (wasDeleted)
1032 return;
1033
1034#if QT_CONFIG(thread)
1035 currentLookups.removeOne(r);
1036#endif
1038 rescheduleWithMutexHeld();
1039}
1040
1041// This function returns immediately when we had a result in the cache, else it will later emit a signal
1042QHostInfo qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id)
1043{
1044 *valid = false;
1045 *id = -1;
1046
1047 // check cache
1048 QHostInfoLookupManager* manager = theHostInfoLookupManager();
1049 if (manager && manager->cache.isEnabled()) {
1050 QHostInfo info = manager->cache.get(name, valid);
1051 if (*valid) {
1052 return info;
1053 }
1054 }
1055
1056 // was not in cache, trigger lookup
1057 *id = QHostInfo::lookupHostImpl(name, receiver, nullptr, member);
1058
1059 // return empty response, valid==false
1060 return QHostInfo();
1061}
1062
1064{
1065 QHostInfoLookupManager* manager = theHostInfoLookupManager();
1066 if (manager) {
1067 manager->clear();
1068 }
1069}
1070
1071#ifdef QT_BUILD_INTERNAL
1073{
1074 QHostInfoLookupManager* manager = theHostInfoLookupManager();
1075 if (manager) {
1076 manager->cache.setEnabled(e);
1077 }
1078}
1079
1080void qt_qhostinfo_cache_inject(const QString &hostname, const QHostInfo &resolution)
1081{
1082 QHostInfoLookupManager* manager = theHostInfoLookupManager();
1083 if (!manager || !manager->cache.isEnabled())
1084 return;
1085
1086 manager->cache.put(hostname, resolution);
1087}
1088#endif
1089
1090// cache for 60 seconds
1091// cache 128 items
1093{
1094#ifdef QT_QHOSTINFO_CACHE_DISABLED_BY_DEFAULT
1095 enabled.store(false, std::memory_order_relaxed);
1096#endif
1097}
1098
1100{
1101 QMutexLocker locker(&this->mutex);
1102
1103 *valid = false;
1104 if (QHostInfoCacheElement *element = cache.object(name)) {
1105 if (element->age.elapsed() < max_age*1000)
1106 *valid = true;
1107 return element->info;
1108
1109 // FIXME idea:
1110 // if too old but not expired, trigger a new lookup
1111 // to freshen our cache
1112 }
1113
1114 return QHostInfo();
1115}
1116
1118{
1119 // if the lookup failed, don't cache
1120 if (info.error() != QHostInfo::NoError)
1121 return;
1122
1123 QHostInfoCacheElement* element = new QHostInfoCacheElement();
1124 element->info = info;
1125 element->age = QElapsedTimer();
1126 element->age.start();
1127
1128 QMutexLocker locker(&this->mutex);
1129 cache.insert(name, element); // cache will take ownership
1130}
1131
1133{
1134 QMutexLocker locker(&this->mutex);
1135 cache.clear();
1136}
1137
1139
1140#include "moc_qhostinfo_p.cpp"
static QAbstractEventDispatcher * instance(QThread *thread=nullptr)
Returns a pointer to the event dispatcher object for the specified thread.
static constexpr auto IPv4Protocol
\inmodule QtCore
Definition qbytearray.h:57
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:106
static QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
static QString translate(const char *context, const char *key, const char *disambiguation=nullptr, int n=-1)
\threadsafe
\inmodule QtCore
\inmodule QtCore
Definition qcoreevent.h:45
@ MetaCall
Definition qcoreevent.h:97
The QHostAddress class provides an IP address.
static QHostInfo lookup(const QString &hostName)
static QHostInfo reverseLookup(const QHostAddress &address)
static QHostInfo fromName(const QString &hostName)
QHostInfo get(const QString &name, bool *valid)
const int max_age
void put(const QString &name, const QHostInfo &info)
QQueue< QHostInfoRunnable * > scheduledLookups
void lookupFinished(QHostInfoRunnable *r)
void scheduleLookup(QHostInfoRunnable *r)
void abortLookup(int id)
QList< int > abortedLookups
QHostInfoCache cache
QList< QHostInfoRunnable * > finishedLookups
void resultsReady(const QHostInfo &info)
bool event(QEvent *event) override
This virtual function receives events to an object and should return true if the event e was recogniz...
void postResultsReady(const QHostInfo &info)
Definition qhostinfo.cpp:86
void run() override
Implement this pure virtual function in your subclass.
QHostInfoRunnable(const QString &hn, int i, const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj)
QHostInfoResult resultEmitter
The QHostInfo class provides static functions for host name lookups.
Definition qhostinfo.h:19
void setHostName(const QString &name)
Sets the host name of this QHostInfo to hostName.
static int lookupHost(const QString &name, QObject *receiver, const char *member)
Looks up the IP address(es) associated with host name name, and returns an ID for the lookup.
static void abortHostLookup(int lookupId)
Aborts the host lookup with the ID id, as returned by lookupHost().
void setAddresses(const QList< QHostAddress > &addresses)
Sets the list of addresses in this QHostInfo to addresses.
QHostInfo & operator=(const QHostInfo &d)
Assigns the data of the other object to this host info object, and returns a reference to it.
static QString localHostName()
Returns this machine's host name, if one is configured.
HostInfoError
This enum describes the various errors that can occur when trying to resolve a host name.
Definition qhostinfo.h:21
@ HostNotFound
Definition qhostinfo.h:23
@ UnknownError
Definition qhostinfo.h:24
HostInfoError error() const
Returns the type of error that occurred if the host name lookup failed; otherwise returns NoError.
void setError(HostInfoError error)
Sets the error type of this QHostInfo to error.
QHostInfo(int lookupId=-1)
Constructs an empty host info object with lookup ID id.
QString hostName() const
Returns the name of the host whose IP addresses were looked up.
QString errorString() const
If the lookup failed, this function returns a human readable description of the error; otherwise "Unk...
static QHostInfo fromName(const QString &name)
Looks up the IP address(es) for the given host name.
void setErrorString(const QString &errorString)
Sets the human readable description of the error that occurred to str if the lookup failed.
QList< QHostAddress > addresses() const
Returns the list of IP addresses associated with hostName().
int lookupId() const
Returns the ID of this lookup.
void setLookupId(int id)
Sets the ID of this lookup to id.
~QHostInfo()
Destroys the host info object.
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
const_pointer constData() const noexcept
Definition qlist.h:416
bool isEmpty() const noexcept
Definition qlist.h:390
iterator erase(const_iterator begin, const_iterator end)
Definition qlist.h:882
iterator end()
Definition qlist.h:609
T takeAt(qsizetype i)
Definition qlist.h:592
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
value_type takeFirst()
Definition qlist.h:549
qsizetype removeAll(const AT &t)
Definition qlist.h:575
qsizetype count() const noexcept
Definition qlist.h:387
iterator begin()
Definition qlist.h:608
void append(parameter_type t)
Definition qlist.h:441
void clear()
Definition qlist.h:417
static QMetaCallEvent * create(QtPrivate::QSlotObjectBase *slotObj, const QObject *sender, int signal_index, const Args &...argv)
Definition qobject_p.h:391
\inmodule QtCore
Definition qmutex.h:317
void unlock() noexcept
Unlocks this mutex locker.
Definition qmutex.h:323
QAbstractNetworkCache * cache() const
\inmodule QtCore
Definition qobject.h:90
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
virtual bool event(QEvent *event)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition qobject.cpp:1363
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
void deleteLater()
\threadsafe
Definition qobject.cpp:2352
T * data() const
Definition qpointer.h:56
void enqueue(const T &t)
Adds value t to the tail of the queue.
Definition qqueue.h:18
void setAutoDelete(bool autoDelete)
Enables auto-deletion if autoDelete is true; otherwise auto-deletion is disabled.
Definition qrunnable.h:38
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
QByteArray toLatin1() const &
Definition qstring.h:559
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5710
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5788
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
Definition qstring.h:1164
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:7822
static QString machineHostName()
Definition qsysinfo.cpp:926
static QThread * currentThread()
Definition qthread.cpp:966
static QByteArray toAce(const QString &domain, AceProcessingOptions options={})
Definition qurl.cpp:3061
void call(QObject *r, void **a)
QString str
[2]
qDeleteAll(list.begin(), list.end())
double e
QCache< int, Employee > cache
[0]
QSet< QString >::iterator it
auto signal
Combined button and popup list for selecting options.
@ QueuedConnection
@ DirectConnection
#define Q_APPLICATION_STATIC(TYPE, NAME,...)
#define Q_BASIC_ATOMIC_INITIALIZER(a)
#define Q_UNLIKELY(x)
#define Q_LIKELY(x)
#define qApp
DBusConnection const char DBusError * error
void qt_qhostinfo_clear_cache()
static int nextId()
QHostInfo qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id)
void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e)
void Q_AUTOTEST_EXPORT qt_qhostinfo_cache_inject(const QString &hostname, const QHostInfo &resolution)
#define NI_MAXHOST
#define qDebug
[1]
Definition qlogging.h:160
#define qWarning
Definition qlogging.h:162
#define QT_IMPL_METATYPE_EXTERN(TYPE)
Definition qmetatype.h:1369
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
#define AF_INET6
#define SIGNAL(a)
Definition qobjectdefs.h:52
GLboolean r
[2]
GLenum GLuint id
[7]
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLuint name
GLint first
GLuint counter
struct _cl_event * event
GLuint res
GLenum const void * addr
GLuint GLuint64EXT address
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
Definition qscopeguard.h:60
#define Q_AUTOTEST_EXPORT
#define emit
static uint nextId
Q_CHECK_PTR(a=new int[80])
QFileInfo info(fileName)
[8]
QMutex mutex
[2]
QSharedPointer< T > other(t)
[5]
QNetworkAccessManager manager
QJSValueList args
bool contains(const AT &t) const noexcept
Definition qlist.h:44
static int signalOffset(const QMetaObject *m)