Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
76 : receiver{receiver ? receiver : this}, slotObj{std::move(slot)}
77{
78 Q_ASSERT(this->receiver);
79 moveToThread(this->receiver->thread());
80}
81
83 = default;
84
85/*
86 The calling thread is likely the one that executes the lookup via
87 QHostInfoRunnable. Unless we operate with a queued connection already,
88 posts the QHostInfo to a dedicated QHostInfoResult object that lives in
89 the same thread as the user-provided receiver, or (if there is none) in
90 the thread that made the call to lookupHost. That QHostInfoResult object
91 then calls the user code in the correct thread.
92
93 The 'result' object deletes itself (via deleteLater) when
94 finalizePostResultsReady is called.
95*/
97{
98 // queued connection will take care of dispatching to right thread
99 if (!slotObj) {
101 return;
102 }
103 // we used to have a context object, but it's already destroyed
104 if (!receiver)
105 return;
106
107 // a long-living version of this
108 auto result = new QHostInfoResult(this);
110
112 &QHostInfoResult::finalizePostResultsReady,
114 info);
115}
116
117/*
118 Receives the info from postResultsReady, and calls the functor.
119*/
120void QHostInfoResult::finalizePostResultsReady(const QHostInfo &info)
121{
122 Q_ASSERT(slotObj);
123
124 // we used to have a context object, but it's already destroyed
125 if (receiver) {
126 void *args[] = { nullptr, const_cast<QHostInfo *>(&info) };
127 slotObj->call(const_cast<QObject *>(receiver.data()), args);
128 }
129
130 deleteLater();
131}
132
191static int nextId()
192{
193 Q_CONSTINIT static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(0);
194 return 1 + counter.fetchAndAddRelaxed(1);
195}
196
229int QHostInfo::lookupHost(const QString &name, const QObject *receiver, const char *member)
230{
231 if (!receiver || !member) {
232 qWarning("QHostInfo::lookupHost: both the receiver and the member to invoke must be non-null");
233 return -1;
234 }
235 return QHostInfo::lookupHostImpl(name, receiver, nullptr, member);
236}
237
321{
322 theHostInfoLookupManager()->abortLookup(id);
323}
324
339{
340#if defined QHOSTINFO_DEBUG
341 qDebug("QHostInfo::fromName(\"%s\")",name.toLatin1().constData());
342#endif
343
344#ifdef Q_OS_WASM
346#else
348 QHostInfoLookupManager* manager = theHostInfoLookupManager();
349 manager->cache.put(name, hostInfo);
350 return hostInfo;
351#endif
352}
353
354
356{
358 // Reverse lookup
359 sockaddr_in sa4;
360 sockaddr_in6 sa6;
361 sockaddr *sa = nullptr;
362 QT_SOCKLEN_T saSize;
363 if (address.protocol() == QAbstractSocket::IPv4Protocol) {
364 sa = reinterpret_cast<sockaddr *>(&sa4);
365 saSize = sizeof(sa4);
366 memset(&sa4, 0, sizeof(sa4));
367 sa4.sin_family = AF_INET;
368 sa4.sin_addr.s_addr = htonl(address.toIPv4Address());
369 } else {
370 sa = reinterpret_cast<sockaddr *>(&sa6);
371 saSize = sizeof(sa6);
372 memset(&sa6, 0, sizeof(sa6));
373 sa6.sin6_family = AF_INET6;
374 memcpy(&sa6.sin6_addr, address.toIPv6Address().c, sizeof(sa6.sin6_addr));
375 }
376
377 char hbuf[NI_MAXHOST];
378 if (sa && getnameinfo(sa, saSize, hbuf, sizeof(hbuf), nullptr, 0, 0) == 0)
379 results.setHostName(QString::fromLatin1(hbuf));
380
381 if (results.hostName().isEmpty())
382 results.setHostName(address.toString());
383 results.setAddresses(QList<QHostAddress>() << address);
384
385 return results;
386}
387
388/*
389 Call getaddrinfo, and returns the results as QHostInfo::addresses
390*/
392{
394
395 // IDN support
396 QByteArray aceHostname = QUrl::toAce(hostName);
397 results.setHostName(hostName);
398 if (aceHostname.isEmpty()) {
400 results.setErrorString(hostName.isEmpty() ?
401 QCoreApplication::translate("QHostInfoAgent", "No host name given") :
402 QCoreApplication::translate("QHostInfoAgent", "Invalid hostname"));
403 return results;
404 }
405
406 addrinfo *res = nullptr;
407 struct addrinfo hints;
408 memset(&hints, 0, sizeof(hints));
409 hints.ai_family = PF_UNSPEC;
410#ifdef Q_ADDRCONFIG
411 hints.ai_flags = Q_ADDRCONFIG;
412#endif
413
414 int result = getaddrinfo(aceHostname.constData(), nullptr, &hints, &res);
415# ifdef Q_ADDRCONFIG
416 if (result == EAI_BADFLAGS) {
417 // if the lookup failed with AI_ADDRCONFIG set, try again without it
418 hints.ai_flags = 0;
419 result = getaddrinfo(aceHostname.constData(), nullptr, &hints, &res);
420 }
421# endif
422
423 if (result == 0) {
424 addrinfo *node = res;
425 QList<QHostAddress> addresses;
426 while (node) {
427#ifdef QHOSTINFO_DEBUG
428 qDebug() << "getaddrinfo node: flags:" << node->ai_flags << "family:" << node->ai_family
429 << "ai_socktype:" << node->ai_socktype << "ai_protocol:" << node->ai_protocol
430 << "ai_addrlen:" << node->ai_addrlen;
431#endif
432 switch (node->ai_family) {
433 case AF_INET: {
435 addr.setAddress(ntohl(((sockaddr_in *) node->ai_addr)->sin_addr.s_addr));
436 if (!addresses.contains(addr))
437 addresses.append(addr);
438 break;
439 }
440 case AF_INET6: {
442 sockaddr_in6 *sa6 = (sockaddr_in6 *) node->ai_addr;
443 addr.setAddress(sa6->sin6_addr.s6_addr);
444 if (sa6->sin6_scope_id)
445 addr.setScopeId(QString::number(sa6->sin6_scope_id));
446 if (!addresses.contains(addr))
447 addresses.append(addr);
448 break;
449 }
450 default:
452 results.setErrorString(QCoreApplication::translate("QHostInfoAgent", "Unknown address type"));
453 }
454 node = node->ai_next;
455 }
456 if (addresses.isEmpty()) {
457 // Reached the end of the list, but no addresses were found; this
458 // means the list contains one or more unknown address types.
460 results.setErrorString(QCoreApplication::translate("QHostInfoAgent", "Unknown address type"));
461 }
462
463 results.setAddresses(addresses);
464 freeaddrinfo(res);
465 } else {
466 switch (result) {
467#ifdef Q_OS_WIN
468 case WSAHOST_NOT_FOUND: //authoritative not found
469 case WSATRY_AGAIN: //non authoritative not found
470 case WSANO_DATA: //valid name, no associated address
471#else
472 case EAI_NONAME:
473 case EAI_FAIL:
474# ifdef EAI_NODATA // EAI_NODATA is deprecated in RFC 3493
475 case EAI_NODATA:
476# endif
477#endif
479 results.setErrorString(QCoreApplication::translate("QHostInfoAgent", "Host not found"));
480 break;
481 default:
483#ifdef Q_OS_WIN
484 results.setErrorString(QString::fromWCharArray(gai_strerror(result)));
485#else
486 results.setErrorString(QString::fromLocal8Bit(gai_strerror(result)));
487#endif
488 break;
489 }
490 }
491
492#if defined(QHOSTINFO_DEBUG)
493 if (results.error() != QHostInfo::NoError) {
494 qDebug("QHostInfoAgent::fromName(): error #%d %s",
495 h_errno, results.errorString().toLatin1().constData());
496 } else {
497 QString tmp;
498 QList<QHostAddress> addresses = results.addresses();
499 for (int i = 0; i < addresses.count(); ++i) {
500 if (i != 0) tmp += ", "_L1;
501 tmp += addresses.at(i).toString();
502 }
503 qDebug("QHostInfoAgent::fromName(): found %i entries for \"%s\": {%s}",
504 addresses.count(), aceHostname.constData(),
505 tmp.toLatin1().constData());
506 }
507#endif
508
509 return results;
510}
511
531 : d_ptr(new QHostInfoPrivate)
532{
533 Q_D(QHostInfo);
534 d->lookupId = id;
535}
536
541 : d_ptr(new QHostInfoPrivate(*other.d_ptr))
542{
543}
544
562{
563 if (this == &other)
564 return *this;
565
566 Q_ASSERT(d_ptr && other.d_ptr);
567 *d_ptr = *other.d_ptr;
568 return *this;
569}
570
575{
576 delete d_ptr;
577}
578
589QList<QHostAddress> QHostInfo::addresses() const
590{
591 Q_D(const QHostInfo);
592 return d->addrs;
593}
594
600void QHostInfo::setAddresses(const QList<QHostAddress> &addresses)
601{
602 Q_D(QHostInfo);
603 d->addrs = addresses;
604}
605
612{
613 Q_D(const QHostInfo);
614 return d->hostName;
615}
616
622void QHostInfo::setHostName(const QString &hostName)
623{
624 Q_D(QHostInfo);
625 d->hostName = hostName;
626}
627
635{
636 Q_D(const QHostInfo);
637 return d->err;
638}
639
646{
647 Q_D(QHostInfo);
648 d->err = error;
649}
650
657{
658 Q_D(const QHostInfo);
659 return d->lookupId;
660}
661
668{
669 Q_D(QHostInfo);
670 d->lookupId = id;
671}
672
680{
681 Q_D(const QHostInfo);
682 return d->errorStr;
683}
684
692{
693 Q_D(QHostInfo);
694 d->errorStr = str;
695}
696
716
737int QHostInfo::lookupHostImpl(const QString &name,
738 const QObject *receiver,
739 QtPrivate::QSlotObjectBase *slotObjRaw,
740 const char *member)
741{
742 QtPrivate::SlotObjUniquePtr slotObj{slotObjRaw};
743#if defined QHOSTINFO_DEBUG
744 qDebug("QHostInfo::lookupHostImpl(\"%s\", %p, %p, %s)",
745 name.toLatin1().constData(), receiver, slotObj.get(), member ? member + 1 : 0);
746#endif
747 Q_ASSERT(!member != !slotObj); // one of these must be set, but not both
748 Q_ASSERT(receiver || slotObj);
749 Q_ASSERT(!member || receiver); // if member is set, also is receiver
750 const bool isUsingStringBasedSlot = static_cast<bool>(member);
751
753 qWarning("QHostInfo::lookupHost() called with no event dispatcher");
754 return -1;
755 }
756
757 qRegisterMetaType<QHostInfo>();
758
759 int id = nextId(); // generate unique ID
760
761 if (Q_UNLIKELY(name.isEmpty())) {
762 QHostInfo hostInfo(id);
763 hostInfo.setError(QHostInfo::HostNotFound);
764 hostInfo.setErrorString(QCoreApplication::translate("QHostInfo", "No host name given"));
765
766 QHostInfoResult result(receiver, std::move(slotObj));
767 if (isUsingStringBasedSlot) {
768 QObject::connect(&result, SIGNAL(resultsReady(QHostInfo)),
769 receiver, member, Qt::QueuedConnection);
770 }
771 result.postResultsReady(hostInfo);
772
773 return id;
774 }
775
776#ifdef Q_OS_WASM
777 // Resolve the host name directly without using a thread or cache,
778 // since Emscripten's host lookup is fast. Emscripten maintains an internal
779 // mapping of hosts and addresses for the purposes of WebSocket socket
780 // tunnelling, and does not perform an actual host lookup.
782 hostInfo.setLookupId(id);
783
784 QHostInfoResult result(receiver, std::move(slotObj));
785 if (isUsingStringBasedSlot) {
786 QObject::connect(&result, SIGNAL(resultsReady(QHostInfo)),
787 receiver, member, Qt::QueuedConnection);
788 }
789 result.postResultsReady(hostInfo);
790#else
791 QHostInfoLookupManager *manager = theHostInfoLookupManager();
792
793 if (Q_LIKELY(manager)) {
794 // the application is still alive
795 if (manager->cache.isEnabled()) {
796 // check cache first
797 bool valid = false;
798 QHostInfo info = manager->cache.get(name, &valid);
799 if (valid) {
800 info.setLookupId(id);
801 QHostInfoResult result(receiver, std::move(slotObj));
802 if (isUsingStringBasedSlot) {
803 QObject::connect(&result, SIGNAL(resultsReady(QHostInfo)),
804 receiver, member, Qt::QueuedConnection);
805 }
806 result.postResultsReady(info);
807 return id;
808 }
809 }
810
811 // cache is not enabled or it was not in the cache, do normal lookup
812 QHostInfoRunnable *runnable = new QHostInfoRunnable(name, id, receiver, std::move(slotObj));
813 if (isUsingStringBasedSlot) {
814 QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)),
815 receiver, member, Qt::QueuedConnection);
816 }
817 manager->scheduleLookup(runnable);
818 }
819#endif // Q_OS_WASM
820 return id;
821}
822
825 : toBeLookedUp{hn}, id{i}, resultEmitter{receiver, std::move(slotObj)}
826{
827 setAutoDelete(true);
828}
829
831 = default;
832
833// the QHostInfoLookupManager will at some point call this via a QThreadPool
835{
836 QHostInfoLookupManager *manager = theHostInfoLookupManager();
837 const auto sg = qScopeGuard([&] { manager->lookupFinished(this); });
838 // check aborted
839 if (manager->wasAborted(id))
840 return;
841
842 QHostInfo hostInfo;
843
844 // QHostInfo::lookupHost already checks the cache. However we need to check
845 // it here too because it might have been cache saved by another QHostInfoRunnable
846 // in the meanwhile while this QHostInfoRunnable was scheduled but not running
847 if (manager->cache.isEnabled()) {
848 // check the cache first
849 bool valid = false;
850 hostInfo = manager->cache.get(toBeLookedUp, &valid);
851 if (!valid) {
852 // not in cache, we need to do the lookup and store the result in the cache
854 manager->cache.put(toBeLookedUp, hostInfo);
855 }
856 } else {
857 // cache is not enabled, just do the lookup and continue
859 }
860
861 // check aborted again
862 if (manager->wasAborted(id))
863 return;
864
865 // signal emission
866 hostInfo.setLookupId(id);
868
869#if QT_CONFIG(thread)
870 // now also iterate through the postponed ones
871 {
872 QMutexLocker locker(&manager->mutex);
873 const auto partitionBegin = std::stable_partition(manager->postponedLookups.rbegin(), manager->postponedLookups.rend(),
874 ToBeLookedUpEquals(toBeLookedUp)).base();
875 const auto partitionEnd = manager->postponedLookups.end();
876 for (auto it = partitionBegin; it != partitionEnd; ++it) {
877 QHostInfoRunnable* postponed = *it;
878 // we can now emit
879 hostInfo.setLookupId(postponed->id);
880 postponed->resultEmitter.postResultsReady(hostInfo);
881 delete postponed;
882 }
883 manager->postponedLookups.erase(partitionBegin, partitionEnd);
884 }
885
886#endif
887 // thread goes back to QThreadPool
888}
889
891{
892#if QT_CONFIG(thread)
894 &threadPool, [&](QObject *) { threadPool.waitForDone(); },
896 threadPool.setMaxThreadCount(20); // do up to 20 DNS lookups in parallel
897#endif
898}
899
901{
902 QMutexLocker locker(&mutex);
903 wasDeleted = true;
904 locker.unlock();
905
906 // don't qDeleteAll currentLookups, the QThreadPool has ownership
907 clear();
908}
909
911{
912 {
913 QMutexLocker locker(&mutex);
916#if QT_CONFIG(thread)
917 qDeleteAll(postponedLookups);
918 postponedLookups.clear();
919#endif
922 }
923
924#if QT_CONFIG(thread)
925 threadPool.waitForDone();
926#endif
927 cache.clear();
928}
929
930// assumes mutex is locked by caller
931void QHostInfoLookupManager::rescheduleWithMutexHeld()
932{
933 if (wasDeleted)
934 return;
935
936 // goals of this function:
937 // - launch new lookups via the thread pool
938 // - make sure only one lookup per host/IP is in progress
939
940 if (!finishedLookups.isEmpty()) {
941 // remove ID from aborted if it is in there
942 for (int i = 0; i < finishedLookups.size(); i++) {
944 }
945
947 }
948
949#if QT_CONFIG(thread)
950 auto isAlreadyRunning = [this](QHostInfoRunnable *lookup) {
951 return std::any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp));
952 };
953
954 // Transfer any postponed lookups that aren't currently running to the scheduled list, keeping already-running lookups:
955 postponedLookups.erase(separate_if(postponedLookups.begin(),
956 postponedLookups.end(),
957 postponedLookups.begin(),
958 std::front_inserter(scheduledLookups), // prepend! we want to finish it ASAP
959 isAlreadyRunning).first,
960 postponedLookups.end());
961
962 // Unschedule and postpone any that are currently running:
965 std::back_inserter(postponedLookups),
967 isAlreadyRunning).second,
969
970 const int availableThreads = std::max(threadPool.maxThreadCount(), 1) - currentLookups.size();
971 if (availableThreads > 0) {
972 int readyToStartCount = qMin(availableThreads, scheduledLookups.size());
973 auto it = scheduledLookups.begin();
974 while (readyToStartCount--) {
975 // runnable now running in new thread, track this in currentLookups
976 threadPool.start(*it);
977 currentLookups.push_back(std::move(*it));
978 ++it;
979 }
981 }
982#else
985#endif
986}
987
988// called by QHostInfo
990{
991 QMutexLocker locker(&this->mutex);
992
993 if (wasDeleted)
994 return;
995
997 rescheduleWithMutexHeld();
998}
999
1000// called by QHostInfo
1002{
1003 QMutexLocker locker(&this->mutex);
1004
1005 if (wasDeleted)
1006 return;
1007
1008 if (id == -1)
1009 return;
1010
1011#if QT_CONFIG(thread)
1012 // is postponed? delete and return
1013 for (int i = 0; i < postponedLookups.size(); i++) {
1014 if (postponedLookups.at(i)->id == id) {
1015 delete postponedLookups.takeAt(i);
1016 return;
1017 }
1018 }
1019#endif
1020
1021 // is scheduled? delete and return
1022 for (int i = 0; i < scheduledLookups.size(); i++) {
1023 if (scheduledLookups.at(i)->id == id) {
1024 delete scheduledLookups.takeAt(i);
1025 return;
1026 }
1027 }
1028
1029 if (!abortedLookups.contains(id))
1031}
1032
1033// called from QHostInfoRunnable
1035{
1036 QMutexLocker locker(&this->mutex);
1037
1038 if (wasDeleted)
1039 return true;
1040
1041 return abortedLookups.contains(id);
1042}
1043
1044// called from QHostInfoRunnable
1046{
1047 QMutexLocker locker(&this->mutex);
1048
1049 if (wasDeleted)
1050 return;
1051
1052#if QT_CONFIG(thread)
1053 currentLookups.removeOne(r);
1054#endif
1056 rescheduleWithMutexHeld();
1057}
1058
1059// This function returns immediately when we had a result in the cache, else it will later emit a signal
1060QHostInfo qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id)
1061{
1062 *valid = false;
1063 *id = -1;
1064
1065 // check cache
1066 QHostInfoLookupManager* manager = theHostInfoLookupManager();
1067 if (manager && manager->cache.isEnabled()) {
1068 QHostInfo info = manager->cache.get(name, valid);
1069 if (*valid) {
1070 return info;
1071 }
1072 }
1073
1074 // was not in cache, trigger lookup
1075 *id = QHostInfo::lookupHostImpl(name, receiver, nullptr, member);
1076
1077 // return empty response, valid==false
1078 return QHostInfo();
1079}
1080
1082{
1083 QHostInfoLookupManager* manager = theHostInfoLookupManager();
1084 if (manager) {
1085 manager->clear();
1086 }
1087}
1088
1089#ifdef QT_BUILD_INTERNAL
1091{
1092 QHostInfoLookupManager* manager = theHostInfoLookupManager();
1093 if (manager) {
1094 manager->cache.setEnabled(e);
1095 }
1096}
1097
1098void qt_qhostinfo_cache_inject(const QString &hostname, const QHostInfo &resolution)
1099{
1100 QHostInfoLookupManager* manager = theHostInfoLookupManager();
1101 if (!manager || !manager->cache.isEnabled())
1102 return;
1103
1104 manager->cache.put(hostname, resolution);
1105}
1106#endif
1107
1108// cache for 60 seconds
1109// cache 128 items
1111{
1112#ifdef QT_QHOSTINFO_CACHE_DISABLED_BY_DEFAULT
1113 enabled.store(false, std::memory_order_relaxed);
1114#endif
1115}
1116
1118{
1119 QMutexLocker locker(&this->mutex);
1120
1121 *valid = false;
1122 if (QHostInfoCacheElement *element = cache.object(name)) {
1123 if (element->age.elapsed() < max_age*1000)
1124 *valid = true;
1125 return element->info;
1126
1127 // FIXME idea:
1128 // if too old but not expired, trigger a new lookup
1129 // to freshen our cache
1130 }
1131
1132 return QHostInfo();
1133}
1134
1136{
1137 // if the lookup failed, don't cache
1138 if (info.error() != QHostInfo::NoError)
1139 return;
1140
1141 QHostInfoCacheElement* element = new QHostInfoCacheElement();
1142 element->info = info;
1143 element->age = QElapsedTimer();
1144 element->age.start();
1145
1146 QMutexLocker locker(&this->mutex);
1147 cache.insert(name, element); // cache will take ownership
1148}
1149
1151{
1152 QMutexLocker locker(&this->mutex);
1153 cache.clear();
1154}
1155
1157
1158#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:124
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
void start() noexcept
\typealias QElapsedTimer::Duration Synonym for std::chrono::nanoseconds.
The QHostAddress class provides an IP address.
void setAddress(quint32 ip4Addr)
Set the IPv4 address specified by ip4Addr.
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)
QList< int > abortedLookups
QHostInfoCache cache
QList< QHostInfoRunnable * > finishedLookups
void resultsReady(const QHostInfo &info)
QHostInfoResult(const QObject *receiver, QtPrivate::SlotObjUniquePtr slot)
Definition qhostinfo.cpp:75
void postResultsReady(const QHostInfo &info)
Definition qhostinfo.cpp:96
~QHostInfoResult() override
void run() override
Implement this pure virtual function in your subclass.
QHostInfoRunnable(const QString &hn, int i, const QObject *receiver, QtPrivate::SlotObjUniquePtr slotObj)
QHostInfoResult resultEmitter
~QHostInfoRunnable() override
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 void abortHostLookup(int lookupId)
Aborts the host lookup with the ID id, as returned by lookupHost().
static int lookupHost(const QString &name, const QObject *receiver, const char *member)
Looks up the IP address(es) associated with host name name, and returns an ID for the lookup.
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:22
@ HostNotFound
Definition qhostinfo.h:24
@ UnknownError
Definition qhostinfo.h:25
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.
qsizetype size() const noexcept
Definition qlist.h:397
const_pointer constData() const noexcept
Definition qlist.h:433
bool isEmpty() const noexcept
Definition qlist.h:401
iterator erase(const_iterator begin, const_iterator end)
Definition qlist.h:889
iterator end()
Definition qlist.h:626
T takeAt(qsizetype i)
Definition qlist.h:609
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
value_type takeFirst()
Definition qlist.h:566
qsizetype removeAll(const AT &t)
Definition qlist.h:592
iterator begin()
Definition qlist.h:625
void append(parameter_type t)
Definition qlist.h:458
void clear()
Definition qlist.h:434
\inmodule QtCore
Definition qmutex.h:313
void unlock() noexcept
Unlocks this mutex locker.
Definition qmutex.h:319
QAbstractNetworkCache * cache() const
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
QThread * thread() const
Returns the thread in which the object lives.
Definition qobject.cpp:1598
bool moveToThread(QThread *thread QT6_DECL_NEW_OVERLOAD_TAIL)
Changes the thread affinity for this object and its children and returns true on success.
Definition qobject.cpp:1643
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:2435
T * data() const noexcept
Definition qpointer.h:73
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:129
QByteArray toLatin1() const &
Definition qstring.h:630
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5949
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
Definition qstring.h:1309
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:8084
static QString machineHostName()
Definition qsysinfo.cpp:929
static QThread * currentThread()
Definition qthread.cpp:1039
static QByteArray toAce(const QString &domain, AceProcessingOptions options={})
Definition qurl.cpp:3064
#define this
Definition dialogs.cpp:9
QString str
[2]
qDeleteAll(list.begin(), list.end())
QCache< int, Employee > cache
[0]
QSet< QString >::iterator it
Combined button and popup list for selecting options.
std::unique_ptr< QSlotObjectBase, QSlotObjectBase::Deleter > SlotObjUniquePtr
@ QueuedConnection
@ DirectConnection
#define Q_APPLICATION_STATIC(TYPE, NAME,...)
#define Q_BASIC_ATOMIC_INITIALIZER(a)
#define Q_UNLIKELY(x)
#define Q_LIKELY(x)
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:164
#define qWarning
Definition qlogging.h:166
#define QT_IMPL_METATYPE_EXTERN(TYPE)
Definition qmetatype.h:1390
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
#define AF_INET6
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLboolean r
[2]
GLenum GLuint id
[7]
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLuint name
GLint first
GLuint counter
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])
QMutex mutex
[2]
QSharedPointer< T > other(t)
[5]
QNetworkAccessManager manager
QHostInfo info
[0]
QJSValueList args
bool contains(const AT &t) const noexcept
Definition qlist.h:45
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...