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#ifndef QHOSTINFO_P_H
5#define QHOSTINFO_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists for the convenience
12// of the QHostInfo class. This header file may change from
13// version to version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtNetwork/private/qtnetworkglobal_p.h>
19#include "QtCore/qcoreapplication.h"
20#include "private/qcoreapplication_p.h"
21#include "private/qmetaobject_p.h"
22#include "QtNetwork/qhostinfo.h"
23#include "QtCore/qmutex.h"
24#include "QtCore/qwaitcondition.h"
25#include "QtCore/qobject.h"
26#include "QtCore/qpointer.h"
27#include "QtCore/qthread.h"
28#if QT_CONFIG(thread)
29#include "QtCore/qthreadpool.h"
30#endif
31#include "QtCore/qrunnable.h"
32#include "QtCore/qlist.h"
33#include "QtCore/qqueue.h"
34#include <QElapsedTimer>
35#include <QCache>
36
37#include <atomic>
38
39QT_BEGIN_NAMESPACE
40
41
42class QHostInfoResult : public QObject
43{
44 Q_OBJECT
45public:
46 explicit QHostInfoResult(const QObject *receiver, QtPrivate::SlotObjUniquePtr slot);
47 ~QHostInfoResult() override;
48
49 void postResultsReady(const QHostInfo &info);
50
51Q_SIGNALS:
52 void resultsReady(const QHostInfo &info);
53
54private Q_SLOTS:
55 void finalizePostResultsReady(const QHostInfo &info);
56
57private:
58 QHostInfoResult(QHostInfoResult *other)
59 : receiver(other->receiver.get() != other ? other->receiver.get() : this),
60 slotObj{std::move(other->slotObj)}
61 {
62 // cleanup if the application terminates before results are delivered
63 connect(sender: QCoreApplication::instance(), signal: &QCoreApplication::aboutToQuit,
64 context: this, slot: &QObject::deleteLater);
65 // maintain thread affinity
66 moveToThread(thread: other->thread());
67 }
68
69 // receiver is either a QObject provided by the user,
70 // or it's set to `this` (to emulate the behavior of the contextless connect())
71 QPointer<const QObject> receiver = nullptr;
72 QtPrivate::SlotObjUniquePtr slotObj;
73};
74
75class QHostInfoAgent
76{
77public:
78 static QHostInfo fromName(const QString &hostName);
79 static QHostInfo lookup(const QString &hostName);
80 static QHostInfo reverseLookup(const QHostAddress &address);
81};
82
83class QHostInfoPrivate
84{
85public:
86 inline QHostInfoPrivate()
87 : err(QHostInfo::NoError),
88 errorStr(QLatin1StringView(QT_TRANSLATE_NOOP("QHostInfo", "Unknown error"))),
89 lookupId(0)
90 {
91 }
92 static int lookupHostImpl(const QString &name,
93 const QObject *receiver,
94 QtPrivate::QSlotObjectBase *slotObj,
95 const char *member);
96
97 QHostInfo::HostInfoError err;
98 QString errorStr;
99 QList<QHostAddress> addrs;
100 QString hostName;
101 int lookupId;
102};
103
104// These functions are outside of the QHostInfo class and strictly internal.
105// Do NOT use them outside of QAbstractSocket.
106QHostInfo Q_NETWORK_EXPORT qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id);
107void Q_AUTOTEST_EXPORT qt_qhostinfo_clear_cache();
108void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e);
109void Q_AUTOTEST_EXPORT qt_qhostinfo_cache_inject(const QString &hostname, const QHostInfo &resolution);
110
111class QHostInfoCache
112{
113public:
114 QHostInfoCache();
115 const int max_age; // seconds
116
117 QHostInfo get(const QString &name, bool *valid);
118 void put(const QString &name, const QHostInfo &info);
119 void clear();
120
121 bool isEnabled() { return enabled.load(m: std::memory_order_relaxed); }
122 // this function is currently only used for the auto tests
123 // and not usable by public API
124 void setEnabled(bool e) { enabled.store(i: e, m: std::memory_order_relaxed); }
125private:
126 std::atomic<bool> enabled;
127 struct QHostInfoCacheElement {
128 QHostInfo info;
129 QElapsedTimer age;
130 };
131 QCache<QString,QHostInfoCacheElement> cache;
132 QMutex mutex;
133};
134
135// the following classes are used for the (normal) case: We use multiple threads to lookup DNS
136
137class QHostInfoRunnable : public QRunnable
138{
139public:
140 explicit QHostInfoRunnable(const QString &hn, int i, const QObject *receiver,
141 QtPrivate::SlotObjUniquePtr slotObj);
142 ~QHostInfoRunnable() override;
143
144 void run() override;
145
146 QString toBeLookedUp;
147 int id;
148 QHostInfoResult resultEmitter;
149};
150
151
152class QHostInfoLookupManager
153{
154public:
155 QHostInfoLookupManager();
156 ~QHostInfoLookupManager();
157
158 void clear();
159
160 // called from QHostInfo
161 void scheduleLookup(QHostInfoRunnable *r);
162 void abortLookup(int id);
163
164 // called from QHostInfoRunnable
165 void lookupFinished(QHostInfoRunnable *r);
166 bool wasAborted(int id);
167
168 QHostInfoCache cache;
169
170 friend class QHostInfoRunnable;
171protected:
172#if QT_CONFIG(thread)
173 QList<QHostInfoRunnable*> currentLookups; // in progress
174 QList<QHostInfoRunnable*> postponedLookups; // postponed because in progress for same host
175#endif
176 QQueue<QHostInfoRunnable*> scheduledLookups; // not yet started
177 QList<QHostInfoRunnable*> finishedLookups; // recently finished
178 QList<int> abortedLookups; // ids of aborted lookups
179
180#if QT_CONFIG(thread)
181 QThreadPool threadPool;
182#endif
183 QMutex mutex;
184
185 bool wasDeleted;
186
187private:
188 void rescheduleWithMutexHeld();
189};
190
191QT_END_NAMESPACE
192
193#endif // QHOSTINFO_P_H
194

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtbase/src/network/kernel/qhostinfo_p.h