| Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/network/kernel/qhostinfo.cpp |
| Source code | Switch to Preprocessed file |
| Line | Source | Count | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | /**************************************************************************** | - | ||||||||||||
| 2 | ** | - | ||||||||||||
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. | - | ||||||||||||
| 4 | ** Contact: https://www.qt.io/licensing/ | - | ||||||||||||
| 5 | ** | - | ||||||||||||
| 6 | ** This file is part of the QtNetwork module of the Qt Toolkit. | - | ||||||||||||
| 7 | ** | - | ||||||||||||
| 8 | ** $QT_BEGIN_LICENSE:LGPL$ | - | ||||||||||||
| 9 | ** Commercial License Usage | - | ||||||||||||
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | - | ||||||||||||
| 11 | ** accordance with the commercial license agreement provided with the | - | ||||||||||||
| 12 | ** Software or, alternatively, in accordance with the terms contained in | - | ||||||||||||
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | - | ||||||||||||
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | - | ||||||||||||
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | - | ||||||||||||
| 16 | ** | - | ||||||||||||
| 17 | ** GNU Lesser General Public License Usage | - | ||||||||||||
| 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - | ||||||||||||
| 19 | ** General Public License version 3 as published by the Free Software | - | ||||||||||||
| 20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | - | ||||||||||||
| 21 | ** packaging of this file. Please review the following information to | - | ||||||||||||
| 22 | ** ensure the GNU Lesser General Public License version 3 requirements | - | ||||||||||||
| 23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | - | ||||||||||||
| 24 | ** | - | ||||||||||||
| 25 | ** GNU General Public License Usage | - | ||||||||||||
| 26 | ** Alternatively, this file may be used under the terms of the GNU | - | ||||||||||||
| 27 | ** General Public License version 2.0 or (at your option) the GNU General | - | ||||||||||||
| 28 | ** Public license version 3 or any later version approved by the KDE Free | - | ||||||||||||
| 29 | ** Qt Foundation. The licenses are as published by the Free Software | - | ||||||||||||
| 30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | - | ||||||||||||
| 31 | ** included in the packaging of this file. Please review the following | - | ||||||||||||
| 32 | ** information to ensure the GNU General Public License requirements will | - | ||||||||||||
| 33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | - | ||||||||||||
| 34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | - | ||||||||||||
| 35 | ** | - | ||||||||||||
| 36 | ** $QT_END_LICENSE$ | - | ||||||||||||
| 37 | ** | - | ||||||||||||
| 38 | ****************************************************************************/ | - | ||||||||||||
| 39 | - | |||||||||||||
| 40 | #include "qhostinfo.h" | - | ||||||||||||
| 41 | #include "qhostinfo_p.h" | - | ||||||||||||
| 42 | - | |||||||||||||
| 43 | #include "QtCore/qscopedpointer.h" | - | ||||||||||||
| 44 | #include <qabstracteventdispatcher.h> | - | ||||||||||||
| 45 | #include <qcoreapplication.h> | - | ||||||||||||
| 46 | #include <qmetaobject.h> | - | ||||||||||||
| 47 | #include <qstringlist.h> | - | ||||||||||||
| 48 | #include <qthread.h> | - | ||||||||||||
| 49 | #include <qurl.h> | - | ||||||||||||
| 50 | #include <private/qnetworksession_p.h> | - | ||||||||||||
| 51 | - | |||||||||||||
| 52 | #include <algorithm> | - | ||||||||||||
| 53 | - | |||||||||||||
| 54 | #ifdef Q_OS_UNIX | - | ||||||||||||
| 55 | # include <unistd.h> | - | ||||||||||||
| 56 | #endif | - | ||||||||||||
| 57 | - | |||||||||||||
| 58 | QT_BEGIN_NAMESPACE | - | ||||||||||||
| 59 | - | |||||||||||||
| 60 | //#define QHOSTINFO_DEBUG | - | ||||||||||||
| 61 | - | |||||||||||||
| 62 | Q_GLOBAL_STATIC(QHostInfoLookupManager, theHostInfoLookupManager) | - | ||||||||||||
| 63 | - | |||||||||||||
| 64 | namespace { | - | ||||||||||||
| 65 | struct ToBeLookedUpEquals { | - | ||||||||||||
| 66 | typedef bool result_type; | - | ||||||||||||
| 67 | explicit ToBeLookedUpEquals(const QString &toBeLookedUp) Q_DECL_NOTHROW : m_toBeLookedUp(toBeLookedUp) {} executed 22925 times by 18 tests: end of blockExecuted by:
| 22925 | ||||||||||||
| 68 | result_type operator()(QHostInfoRunnable* lookup) const Q_DECL_NOTHROW | - | ||||||||||||
| 69 | { | - | ||||||||||||
| 70 | return m_toBeLookedUp == lookup->toBeLookedUp; executed 45527 times by 4 tests: return m_toBeLookedUp == lookup->toBeLookedUp;Executed by:
| 45527 | ||||||||||||
| 71 | } | - | ||||||||||||
| 72 | private: | - | ||||||||||||
| 73 | QString m_toBeLookedUp; | - | ||||||||||||
| 74 | }; | - | ||||||||||||
| 75 | - | |||||||||||||
| 76 | // ### C++11: remove once we can use std::any_of() | - | ||||||||||||
| 77 | template<class InputIt, class UnaryPredicate> | - | ||||||||||||
| 78 | bool any_of(InputIt first, InputIt last, UnaryPredicate p) | - | ||||||||||||
| 79 | { | - | ||||||||||||
| 80 | return std::find_if(first, last, p) != last; executed 22720 times by 18 tests: return std::find_if(first, last, p) != last;Executed by:
| 22720 | ||||||||||||
| 81 | } | - | ||||||||||||
| 82 | - | |||||||||||||
| 83 | template <typename InputIt, typename OutputIt1, typename OutputIt2, typename UnaryPredicate> | - | ||||||||||||
| 84 | std::pair<OutputIt1, OutputIt2> separate_if(InputIt first, InputIt last, OutputIt1 dest1, OutputIt2 dest2, UnaryPredicate p) | - | ||||||||||||
| 85 | { | - | ||||||||||||
| 86 | while (first != last
| 8148-22720 | ||||||||||||
| 87 | if (p(*first)) {
| 458-22262 | ||||||||||||
| 88 | *dest1 = *first; | - | ||||||||||||
| 89 | ++dest1; | - | ||||||||||||
| 90 | } else { executed 22262 times by 4 tests: end of blockExecuted by:
| 22262 | ||||||||||||
| 91 | *dest2 = *first; | - | ||||||||||||
| 92 | ++dest2; | - | ||||||||||||
| 93 | } executed 458 times by 18 tests: end of blockExecuted by:
| 458 | ||||||||||||
| 94 | ++first; | - | ||||||||||||
| 95 | } executed 22720 times by 18 tests: end of blockExecuted by:
| 22720 | ||||||||||||
| 96 | return std::make_pair(dest1, dest2); executed 8148 times by 19 tests: return std::make_pair(dest1, dest2);Executed by:
| 8148 | ||||||||||||
| 97 | } | - | ||||||||||||
| 98 | } | - | ||||||||||||
| 99 | - | |||||||||||||
| 100 | /*! | - | ||||||||||||
| 101 | \class QHostInfo | - | ||||||||||||
| 102 | \brief The QHostInfo class provides static functions for host name lookups. | - | ||||||||||||
| 103 | - | |||||||||||||
| 104 | \reentrant | - | ||||||||||||
| 105 | \inmodule QtNetwork | - | ||||||||||||
| 106 | \ingroup network | - | ||||||||||||
| 107 | - | |||||||||||||
| 108 | QHostInfo uses the lookup mechanisms provided by the operating | - | ||||||||||||
| 109 | system to find the IP address(es) associated with a host name, | - | ||||||||||||
| 110 | or the host name associated with an IP address. | - | ||||||||||||
| 111 | The class provides two static convenience functions: one that | - | ||||||||||||
| 112 | works asynchronously and emits a signal once the host is found, | - | ||||||||||||
| 113 | and one that blocks and returns a QHostInfo object. | - | ||||||||||||
| 114 | - | |||||||||||||
| 115 | To look up a host's IP addresses asynchronously, call lookupHost(), | - | ||||||||||||
| 116 | which takes the host name or IP address, a receiver object, and a slot | - | ||||||||||||
| 117 | signature as arguments and returns an ID. You can abort the | - | ||||||||||||
| 118 | lookup by calling abortHostLookup() with the lookup ID. | - | ||||||||||||
| 119 | - | |||||||||||||
| 120 | Example: | - | ||||||||||||
| 121 | - | |||||||||||||
| 122 | \snippet code/src_network_kernel_qhostinfo.cpp 0 | - | ||||||||||||
| 123 | - | |||||||||||||
| 124 | - | |||||||||||||
| 125 | The slot is invoked when the results are ready. The results are | - | ||||||||||||
| 126 | stored in a QHostInfo object. Call | - | ||||||||||||
| 127 | addresses() to get the list of IP addresses for the host, and | - | ||||||||||||
| 128 | hostName() to get the host name that was looked up. | - | ||||||||||||
| 129 | - | |||||||||||||
| 130 | If the lookup failed, error() returns the type of error that | - | ||||||||||||
| 131 | occurred. errorString() gives a human-readable description of the | - | ||||||||||||
| 132 | lookup error. | - | ||||||||||||
| 133 | - | |||||||||||||
| 134 | If you want a blocking lookup, use the QHostInfo::fromName() function: | - | ||||||||||||
| 135 | - | |||||||||||||
| 136 | \snippet code/src_network_kernel_qhostinfo.cpp 1 | - | ||||||||||||
| 137 | - | |||||||||||||
| 138 | QHostInfo supports Internationalized Domain Names (IDNs) through the | - | ||||||||||||
| 139 | IDNA and Punycode standards. | - | ||||||||||||
| 140 | - | |||||||||||||
| 141 | To retrieve the name of the local host, use the static | - | ||||||||||||
| 142 | QHostInfo::localHostName() function. | - | ||||||||||||
| 143 | - | |||||||||||||
| 144 | \note Since Qt 4.6.1 QHostInfo is using multiple threads for DNS lookup | - | ||||||||||||
| 145 | instead of one dedicated DNS thread. This improves performance, | - | ||||||||||||
| 146 | but also changes the order of signal emissions when using lookupHost() | - | ||||||||||||
| 147 | compared to previous versions of Qt. | - | ||||||||||||
| 148 | \note Since Qt 4.6.3 QHostInfo is using a small internal 60 second DNS cache | - | ||||||||||||
| 149 | for performance improvements. | - | ||||||||||||
| 150 | - | |||||||||||||
| 151 | \sa QAbstractSocket, {http://www.rfc-editor.org/rfc/rfc3492.txt}{RFC 3492} | - | ||||||||||||
| 152 | */ | - | ||||||||||||
| 153 | - | |||||||||||||
| 154 | static QBasicAtomicInt theIdCounter = Q_BASIC_ATOMIC_INITIALIZER(1); | - | ||||||||||||
| 155 | - | |||||||||||||
| 156 | /*! | - | ||||||||||||
| 157 | Looks up the IP address(es) associated with host name \a name, and | - | ||||||||||||
| 158 | returns an ID for the lookup. When the result of the lookup is | - | ||||||||||||
| 159 | ready, the slot or signal \a member in \a receiver is called with | - | ||||||||||||
| 160 | a QHostInfo argument. The QHostInfo object can then be inspected | - | ||||||||||||
| 161 | to get the results of the lookup. | - | ||||||||||||
| 162 | - | |||||||||||||
| 163 | The lookup is performed by a single function call, for example: | - | ||||||||||||
| 164 | - | |||||||||||||
| 165 | \snippet code/src_network_kernel_qhostinfo.cpp 2 | - | ||||||||||||
| 166 | - | |||||||||||||
| 167 | The implementation of the slot prints basic information about the | - | ||||||||||||
| 168 | addresses returned by the lookup, or reports an error if it failed: | - | ||||||||||||
| 169 | - | |||||||||||||
| 170 | \snippet code/src_network_kernel_qhostinfo.cpp 3 | - | ||||||||||||
| 171 | - | |||||||||||||
| 172 | If you pass a literal IP address to \a name instead of a host name, | - | ||||||||||||
| 173 | QHostInfo will search for the domain name for the IP (i.e., QHostInfo will | - | ||||||||||||
| 174 | perform a \e reverse lookup). On success, the resulting QHostInfo will | - | ||||||||||||
| 175 | contain both the resolved domain name and IP addresses for the host | - | ||||||||||||
| 176 | name. Example: | - | ||||||||||||
| 177 | - | |||||||||||||
| 178 | \snippet code/src_network_kernel_qhostinfo.cpp 4 | - | ||||||||||||
| 179 | - | |||||||||||||
| 180 | \note There is no guarantee on the order the signals will be emitted | - | ||||||||||||
| 181 | if you start multiple requests with lookupHost(). | - | ||||||||||||
| 182 | - | |||||||||||||
| 183 | \sa abortHostLookup(), addresses(), error(), fromName() | - | ||||||||||||
| 184 | */ | - | ||||||||||||
| 185 | int QHostInfo::lookupHost(const QString &name, QObject *receiver, | - | ||||||||||||
| 186 | const char *member) | - | ||||||||||||
| 187 | { | - | ||||||||||||
| 188 | #if defined QHOSTINFO_DEBUG | - | ||||||||||||
| 189 | qDebug("QHostInfo::lookupHost(\"%s\", %p, %s)", | - | ||||||||||||
| 190 | name.toLatin1().constData(), receiver, member ? member + 1 : 0); | - | ||||||||||||
| 191 | #endif | - | ||||||||||||
| 192 | - | |||||||||||||
| 193 | if (!QAbstractEventDispatcher::instance(QThread::currentThread())) { | - | ||||||||||||
| 194 | qWarning("QHostInfo::lookupHost() called with no event dispatcher"); | - | ||||||||||||
| 195 | return -1; | - | ||||||||||||
| 196 | } | - | ||||||||||||
| 197 | - | |||||||||||||
| 198 | qRegisterMetaType<QHostInfo>(); | - | ||||||||||||
| 199 | - | |||||||||||||
| 200 | int id = theIdCounter.fetchAndAddRelaxed(1); // generate unique ID | - | ||||||||||||
| 201 | - | |||||||||||||
| 202 | if (name.isEmpty()) { | - | ||||||||||||
| 203 | if (!receiver) | - | ||||||||||||
| 204 | return -1; | - | ||||||||||||
| 205 | - | |||||||||||||
| 206 | QHostInfo hostInfo(id); | - | ||||||||||||
| 207 | hostInfo.setError(QHostInfo::HostNotFound); | - | ||||||||||||
| 208 | hostInfo.setErrorString(QCoreApplication::translate("QHostInfo", "No host name given")); | - | ||||||||||||
| 209 | QScopedPointer<QHostInfoResult> result(new QHostInfoResult); | - | ||||||||||||
| 210 | QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)), | - | ||||||||||||
| 211 | receiver, member, Qt::QueuedConnection); | - | ||||||||||||
| 212 | result.data()->emitResultsReady(hostInfo); | - | ||||||||||||
| 213 | return id; | - | ||||||||||||
| 214 | } | - | ||||||||||||
| 215 | - | |||||||||||||
| 216 | QHostInfoLookupManager *manager = theHostInfoLookupManager(); | - | ||||||||||||
| 217 | - | |||||||||||||
| 218 | if (manager) { | - | ||||||||||||
| 219 | // the application is still alive | - | ||||||||||||
| 220 | if (manager->cache.isEnabled()) { | - | ||||||||||||
| 221 | // check cache first | - | ||||||||||||
| 222 | bool valid = false; | - | ||||||||||||
| 223 | QHostInfo info = manager->cache.get(name, &valid); | - | ||||||||||||
| 224 | if (valid) { | - | ||||||||||||
| 225 | if (!receiver) | - | ||||||||||||
| 226 | return -1; | - | ||||||||||||
| 227 | - | |||||||||||||
| 228 | info.setLookupId(id); | - | ||||||||||||
| 229 | QHostInfoResult result; | - | ||||||||||||
| 230 | QObject::connect(&result, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection); | - | ||||||||||||
| 231 | result.emitResultsReady(info); | - | ||||||||||||
| 232 | return id; | - | ||||||||||||
| 233 | } | - | ||||||||||||
| 234 | } | - | ||||||||||||
| 235 | - | |||||||||||||
| 236 | // cache is not enabled or it was not in the cache, do normal lookup | - | ||||||||||||
| 237 | QHostInfoRunnable* runnable = new QHostInfoRunnable(name, id); | - | ||||||||||||
| 238 | if (receiver) | - | ||||||||||||
| 239 | QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection); | - | ||||||||||||
| 240 | manager->scheduleLookup(runnable); | - | ||||||||||||
| 241 | } | - | ||||||||||||
| 242 | return id; | - | ||||||||||||
| 243 | } | - | ||||||||||||
| 244 | - | |||||||||||||
| 245 | /*! | - | ||||||||||||
| 246 | Aborts the host lookup with the ID \a id, as returned by lookupHost(). | - | ||||||||||||
| 247 | - | |||||||||||||
| 248 | \sa lookupHost(), lookupId() | - | ||||||||||||
| 249 | */ | - | ||||||||||||
| 250 | void QHostInfo::abortHostLookup(int id) | - | ||||||||||||
| 251 | { | - | ||||||||||||
| 252 | theHostInfoLookupManager()->abortLookup(id); | - | ||||||||||||
| 253 | } | - | ||||||||||||
| 254 | - | |||||||||||||
| 255 | /*! | - | ||||||||||||
| 256 | Looks up the IP address(es) for the given host \a name. The | - | ||||||||||||
| 257 | function blocks during the lookup which means that execution of | - | ||||||||||||
| 258 | the program is suspended until the results of the lookup are | - | ||||||||||||
| 259 | ready. Returns the result of the lookup in a QHostInfo object. | - | ||||||||||||
| 260 | - | |||||||||||||
| 261 | If you pass a literal IP address to \a name instead of a host name, | - | ||||||||||||
| 262 | QHostInfo will search for the domain name for the IP (i.e., QHostInfo will | - | ||||||||||||
| 263 | perform a \e reverse lookup). On success, the returned QHostInfo will | - | ||||||||||||
| 264 | contain both the resolved domain name and IP addresses for the host name. | - | ||||||||||||
| 265 | - | |||||||||||||
| 266 | \sa lookupHost() | - | ||||||||||||
| 267 | */ | - | ||||||||||||
| 268 | QHostInfo QHostInfo::fromName(const QString &name) | - | ||||||||||||
| 269 | { | - | ||||||||||||
| 270 | #if defined QHOSTINFO_DEBUG | - | ||||||||||||
| 271 | qDebug("QHostInfo::fromName(\"%s\")",name.toLatin1().constData()); | - | ||||||||||||
| 272 | #endif | - | ||||||||||||
| 273 | - | |||||||||||||
| 274 | QHostInfo hostInfo = QHostInfoAgent::fromName(name); | - | ||||||||||||
| 275 | QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager(); | - | ||||||||||||
| 276 | manager->cache.put(name, hostInfo); | - | ||||||||||||
| 277 | return hostInfo; | - | ||||||||||||
| 278 | } | - | ||||||||||||
| 279 | - | |||||||||||||
| 280 | #ifndef QT_NO_BEARERMANAGEMENT | - | ||||||||||||
| 281 | QHostInfo QHostInfoPrivate::fromName(const QString &name, QSharedPointer<QNetworkSession> session) | - | ||||||||||||
| 282 | { | - | ||||||||||||
| 283 | #if defined QHOSTINFO_DEBUG | - | ||||||||||||
| 284 | qDebug("QHostInfoPrivate::fromName(\"%s\") with session %p",name.toLatin1().constData(), session.data()); | - | ||||||||||||
| 285 | #endif | - | ||||||||||||
| 286 | - | |||||||||||||
| 287 | QHostInfo hostInfo = QHostInfoAgent::fromName(name, session); | - | ||||||||||||
| 288 | QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager(); | - | ||||||||||||
| 289 | manager->cache.put(name, hostInfo); | - | ||||||||||||
| 290 | return hostInfo; | - | ||||||||||||
| 291 | } | - | ||||||||||||
| 292 | #endif | - | ||||||||||||
| 293 | - | |||||||||||||
| 294 | #ifndef QT_NO_BEARERMANAGEMENT | - | ||||||||||||
| 295 | QHostInfo QHostInfoAgent::fromName(const QString &hostName, QSharedPointer<QNetworkSession>) | - | ||||||||||||
| 296 | { | - | ||||||||||||
| 297 | return QHostInfoAgent::fromName(hostName); | - | ||||||||||||
| 298 | } | - | ||||||||||||
| 299 | #endif | - | ||||||||||||
| 300 | - | |||||||||||||
| 301 | - | |||||||||||||
| 302 | /*! | - | ||||||||||||
| 303 | \enum QHostInfo::HostInfoError | - | ||||||||||||
| 304 | - | |||||||||||||
| 305 | This enum describes the various errors that can occur when trying | - | ||||||||||||
| 306 | to resolve a host name. | - | ||||||||||||
| 307 | - | |||||||||||||
| 308 | \value NoError The lookup was successful. | - | ||||||||||||
| 309 | \value HostNotFound No IP addresses were found for the host. | - | ||||||||||||
| 310 | \value UnknownError An unknown error occurred. | - | ||||||||||||
| 311 | - | |||||||||||||
| 312 | \sa error(), setError() | - | ||||||||||||
| 313 | */ | - | ||||||||||||
| 314 | - | |||||||||||||
| 315 | /*! | - | ||||||||||||
| 316 | Constructs an empty host info object with lookup ID \a id. | - | ||||||||||||
| 317 | - | |||||||||||||
| 318 | \sa lookupId() | - | ||||||||||||
| 319 | */ | - | ||||||||||||
| 320 | QHostInfo::QHostInfo(int id) | - | ||||||||||||
| 321 | : d(new QHostInfoPrivate) | - | ||||||||||||
| 322 | { | - | ||||||||||||
| 323 | d->lookupId = id; | - | ||||||||||||
| 324 | } | - | ||||||||||||
| 325 | - | |||||||||||||
| 326 | /*! | - | ||||||||||||
| 327 | Constructs a copy of \a other. | - | ||||||||||||
| 328 | */ | - | ||||||||||||
| 329 | QHostInfo::QHostInfo(const QHostInfo &other) | - | ||||||||||||
| 330 | : d(new QHostInfoPrivate(*other.d.data())) | - | ||||||||||||
| 331 | { | - | ||||||||||||
| 332 | } | - | ||||||||||||
| 333 | - | |||||||||||||
| 334 | /*! | - | ||||||||||||
| 335 | Assigns the data of the \a other object to this host info object, | - | ||||||||||||
| 336 | and returns a reference to it. | - | ||||||||||||
| 337 | */ | - | ||||||||||||
| 338 | QHostInfo &QHostInfo::operator=(const QHostInfo &other) | - | ||||||||||||
| 339 | { | - | ||||||||||||
| 340 | *d.data() = *other.d.data(); | - | ||||||||||||
| 341 | return *this; | - | ||||||||||||
| 342 | } | - | ||||||||||||
| 343 | - | |||||||||||||
| 344 | /*! | - | ||||||||||||
| 345 | Destroys the host info object. | - | ||||||||||||
| 346 | */ | - | ||||||||||||
| 347 | QHostInfo::~QHostInfo() | - | ||||||||||||
| 348 | { | - | ||||||||||||
| 349 | } | - | ||||||||||||
| 350 | - | |||||||||||||
| 351 | /*! | - | ||||||||||||
| 352 | Returns the list of IP addresses associated with hostName(). This | - | ||||||||||||
| 353 | list may be empty. | - | ||||||||||||
| 354 | - | |||||||||||||
| 355 | Example: | - | ||||||||||||
| 356 | - | |||||||||||||
| 357 | \snippet code/src_network_kernel_qhostinfo.cpp 5 | - | ||||||||||||
| 358 | - | |||||||||||||
| 359 | \sa hostName(), error() | - | ||||||||||||
| 360 | */ | - | ||||||||||||
| 361 | QList<QHostAddress> QHostInfo::addresses() const | - | ||||||||||||
| 362 | { | - | ||||||||||||
| 363 | return d->addrs; | - | ||||||||||||
| 364 | } | - | ||||||||||||
| 365 | - | |||||||||||||
| 366 | /*! | - | ||||||||||||
| 367 | Sets the list of addresses in this QHostInfo to \a addresses. | - | ||||||||||||
| 368 | - | |||||||||||||
| 369 | \sa addresses() | - | ||||||||||||
| 370 | */ | - | ||||||||||||
| 371 | void QHostInfo::setAddresses(const QList<QHostAddress> &addresses) | - | ||||||||||||
| 372 | { | - | ||||||||||||
| 373 | d->addrs = addresses; | - | ||||||||||||
| 374 | } | - | ||||||||||||
| 375 | - | |||||||||||||
| 376 | /*! | - | ||||||||||||
| 377 | Returns the name of the host whose IP addresses were looked up. | - | ||||||||||||
| 378 | - | |||||||||||||
| 379 | \sa localHostName() | - | ||||||||||||
| 380 | */ | - | ||||||||||||
| 381 | QString QHostInfo::hostName() const | - | ||||||||||||
| 382 | { | - | ||||||||||||
| 383 | return d->hostName; | - | ||||||||||||
| 384 | } | - | ||||||||||||
| 385 | - | |||||||||||||
| 386 | /*! | - | ||||||||||||
| 387 | Sets the host name of this QHostInfo to \a hostName. | - | ||||||||||||
| 388 | - | |||||||||||||
| 389 | \sa hostName() | - | ||||||||||||
| 390 | */ | - | ||||||||||||
| 391 | void QHostInfo::setHostName(const QString &hostName) | - | ||||||||||||
| 392 | { | - | ||||||||||||
| 393 | d->hostName = hostName; | - | ||||||||||||
| 394 | } | - | ||||||||||||
| 395 | - | |||||||||||||
| 396 | /*! | - | ||||||||||||
| 397 | Returns the type of error that occurred if the host name lookup | - | ||||||||||||
| 398 | failed; otherwise returns NoError. | - | ||||||||||||
| 399 | - | |||||||||||||
| 400 | \sa setError(), errorString() | - | ||||||||||||
| 401 | */ | - | ||||||||||||
| 402 | QHostInfo::HostInfoError QHostInfo::error() const | - | ||||||||||||
| 403 | { | - | ||||||||||||
| 404 | return d->err; | - | ||||||||||||
| 405 | } | - | ||||||||||||
| 406 | - | |||||||||||||
| 407 | /*! | - | ||||||||||||
| 408 | Sets the error type of this QHostInfo to \a error. | - | ||||||||||||
| 409 | - | |||||||||||||
| 410 | \sa error(), errorString() | - | ||||||||||||
| 411 | */ | - | ||||||||||||
| 412 | void QHostInfo::setError(HostInfoError error) | - | ||||||||||||
| 413 | { | - | ||||||||||||
| 414 | d->err = error; | - | ||||||||||||
| 415 | } | - | ||||||||||||
| 416 | - | |||||||||||||
| 417 | /*! | - | ||||||||||||
| 418 | Returns the ID of this lookup. | - | ||||||||||||
| 419 | - | |||||||||||||
| 420 | \sa setLookupId(), abortHostLookup(), hostName() | - | ||||||||||||
| 421 | */ | - | ||||||||||||
| 422 | int QHostInfo::lookupId() const | - | ||||||||||||
| 423 | { | - | ||||||||||||
| 424 | return d->lookupId; | - | ||||||||||||
| 425 | } | - | ||||||||||||
| 426 | - | |||||||||||||
| 427 | /*! | - | ||||||||||||
| 428 | Sets the ID of this lookup to \a id. | - | ||||||||||||
| 429 | - | |||||||||||||
| 430 | \sa lookupId(), lookupHost() | - | ||||||||||||
| 431 | */ | - | ||||||||||||
| 432 | void QHostInfo::setLookupId(int id) | - | ||||||||||||
| 433 | { | - | ||||||||||||
| 434 | d->lookupId = id; | - | ||||||||||||
| 435 | } | - | ||||||||||||
| 436 | - | |||||||||||||
| 437 | /*! | - | ||||||||||||
| 438 | If the lookup failed, this function returns a human readable | - | ||||||||||||
| 439 | description of the error; otherwise "Unknown error" is returned. | - | ||||||||||||
| 440 | - | |||||||||||||
| 441 | \sa setErrorString(), error() | - | ||||||||||||
| 442 | */ | - | ||||||||||||
| 443 | QString QHostInfo::errorString() const | - | ||||||||||||
| 444 | { | - | ||||||||||||
| 445 | return d->errorStr; | - | ||||||||||||
| 446 | } | - | ||||||||||||
| 447 | - | |||||||||||||
| 448 | /*! | - | ||||||||||||
| 449 | Sets the human readable description of the error that occurred to \a str | - | ||||||||||||
| 450 | if the lookup failed. | - | ||||||||||||
| 451 | - | |||||||||||||
| 452 | \sa errorString(), setError() | - | ||||||||||||
| 453 | */ | - | ||||||||||||
| 454 | void QHostInfo::setErrorString(const QString &str) | - | ||||||||||||
| 455 | { | - | ||||||||||||
| 456 | d->errorStr = str; | - | ||||||||||||
| 457 | } | - | ||||||||||||
| 458 | - | |||||||||||||
| 459 | /*! | - | ||||||||||||
| 460 | \fn QString QHostInfo::localHostName() | - | ||||||||||||
| 461 | - | |||||||||||||
| 462 | Returns this machine's host name, if one is configured. Note that hostnames | - | ||||||||||||
| 463 | are not guaranteed to be globally unique, especially if they were | - | ||||||||||||
| 464 | configured automatically. | - | ||||||||||||
| 465 | - | |||||||||||||
| 466 | This function does not guarantee the returned host name is a Fully | - | ||||||||||||
| 467 | Qualified Domain Name (FQDN). For that, use fromName() to resolve the | - | ||||||||||||
| 468 | returned name to an FQDN. | - | ||||||||||||
| 469 | - | |||||||||||||
| 470 | This function returns the same as QSysInfo::machineHostName(). | - | ||||||||||||
| 471 | - | |||||||||||||
| 472 | \sa hostName(), localDomainName() | - | ||||||||||||
| 473 | */ | - | ||||||||||||
| 474 | QString QHostInfo::localHostName() | - | ||||||||||||
| 475 | { | - | ||||||||||||
| 476 | return QSysInfo::machineHostName(); | - | ||||||||||||
| 477 | } | - | ||||||||||||
| 478 | - | |||||||||||||
| 479 | /*! | - | ||||||||||||
| 480 | \fn QString QHostInfo::localDomainName() | - | ||||||||||||
| 481 | - | |||||||||||||
| 482 | Returns the DNS domain of this machine. | - | ||||||||||||
| 483 | - | |||||||||||||
| 484 | \note DNS domains are not related to domain names found in | - | ||||||||||||
| 485 | Windows networks. | - | ||||||||||||
| 486 | - | |||||||||||||
| 487 | \sa hostName() | - | ||||||||||||
| 488 | */ | - | ||||||||||||
| 489 | - | |||||||||||||
| 490 | QHostInfoRunnable::QHostInfoRunnable(const QString &hn, int i) : toBeLookedUp(hn), id(i) | - | ||||||||||||
| 491 | { | - | ||||||||||||
| 492 | setAutoDelete(true); | - | ||||||||||||
| 493 | } | - | ||||||||||||
| 494 | - | |||||||||||||
| 495 | // the QHostInfoLookupManager will at some point call this via a QThreadPool | - | ||||||||||||
| 496 | void QHostInfoRunnable::run() | - | ||||||||||||
| 497 | { | - | ||||||||||||
| 498 | QHostInfoLookupManager *manager = theHostInfoLookupManager(); | - | ||||||||||||
| 499 | // check aborted | - | ||||||||||||
| 500 | if (manager->wasAborted(id)) {
| 107-329 | ||||||||||||
| 501 | manager->lookupFinished(this); | - | ||||||||||||
| 502 | return; executed 107 times by 9 tests: return;Executed by:
| 107 | ||||||||||||
| 503 | } | - | ||||||||||||
| 504 | - | |||||||||||||
| 505 | QHostInfo hostInfo; | - | ||||||||||||
| 506 | - | |||||||||||||
| 507 | // QHostInfo::lookupHost already checks the cache. However we need to check | - | ||||||||||||
| 508 | // it here too because it might have been cache saved by another QHostInfoRunnable | - | ||||||||||||
| 509 | // in the meanwhile while this QHostInfoRunnable was scheduled but not running | - | ||||||||||||
| 510 | if (manager->cache.isEnabled()) {
| 151-178 | ||||||||||||
| 511 | // check the cache first | - | ||||||||||||
| 512 | bool valid = false; | - | ||||||||||||
| 513 | hostInfo = manager->cache.get(toBeLookedUp, &valid); | - | ||||||||||||
| 514 | if (!valid) {
| 0-151 | ||||||||||||
| 515 | // not in cache, we need to do the lookup and store the result in the cache | - | ||||||||||||
| 516 | hostInfo = QHostInfoAgent::fromName(toBeLookedUp); | - | ||||||||||||
| 517 | manager->cache.put(toBeLookedUp, hostInfo); | - | ||||||||||||
| 518 | } executed 151 times by 14 tests: end of blockExecuted by:
| 151 | ||||||||||||
| 519 | } else { executed 151 times by 14 tests: end of blockExecuted by:
| 151 | ||||||||||||
| 520 | // cache is not enabled, just do the lookup and continue | - | ||||||||||||
| 521 | hostInfo = QHostInfoAgent::fromName(toBeLookedUp); | - | ||||||||||||
| 522 | } executed 178 times by 1 test: end of blockExecuted by:
| 178 | ||||||||||||
| 523 | - | |||||||||||||
| 524 | // check aborted again | - | ||||||||||||
| 525 | if (manager->wasAborted(id)) {
| 124-205 | ||||||||||||
| 526 | manager->lookupFinished(this); | - | ||||||||||||
| 527 | return; executed 124 times by 4 tests: return;Executed by:
| 124 | ||||||||||||
| 528 | } | - | ||||||||||||
| 529 | - | |||||||||||||
| 530 | // signal emission | - | ||||||||||||
| 531 | hostInfo.setLookupId(id); | - | ||||||||||||
| 532 | resultEmitter.emitResultsReady(hostInfo); | - | ||||||||||||
| 533 | - | |||||||||||||
| 534 | // now also iterate through the postponed ones | - | ||||||||||||
| 535 | { | - | ||||||||||||
| 536 | QMutexLocker locker(&manager->mutex); | - | ||||||||||||
| 537 | QMutableListIterator<QHostInfoRunnable*> iteratorconst auto partitionBegin = std::stable_partition(manager->postponedLookups); | - | ||||||||||||
| while (iterator.hasNext()) { | ||||||||||||||
| QHostInfoRunnable* postponed = iteratorrbegin(), manager->postponedLookups.next(); | ||||||||||||||
| ifrend(), | ||||||||||||||
| 538 | ToBeLookedUpEquals(toBeLookedUp== postponed)).base(); | - | ||||||||||||
| 539 | const auto partitionEnd = manager->toBeLookedUppostponedLookups.end(); | - | ||||||||||||
| 540 | for (auto it = partitionBegin; it != partitionEnd; ++it
| 205-475 | ||||||||||||
| 541 | QHostInfoRunnable* postponed = *it; | - | ||||||||||||
| 542 | // we can now emit | - | ||||||||||||
| 543 | iterator.remove();hostInfo.setLookupId(postponed->id); | - | ||||||||||||
| 544 | postponed->resultEmitter.emitResultsReady(hostInfo); | - | ||||||||||||
| 545 | delete postponed; | - | ||||||||||||
| 546 | }} executed 475 times by 2 tests: end of blockExecuted by:
| 475 | ||||||||||||
| 547 | manager->postponedLookups.erase(partitionBegin, partitionEnd); | - | ||||||||||||
| 548 | } | - | ||||||||||||
| 549 | - | |||||||||||||
| 550 | manager->lookupFinished(this); | - | ||||||||||||
| 551 | - | |||||||||||||
| 552 | // thread goes back to QThreadPool | - | ||||||||||||
| 553 | } executed 205 times by 12 tests: end of blockExecuted by:
| 205 | ||||||||||||
| 554 | - | |||||||||||||
| 555 | QHostInfoLookupManager::QHostInfoLookupManager() : mutex(QMutex::Recursive), wasDeleted(false) | - | ||||||||||||
| 556 | { | - | ||||||||||||
| 557 | moveToThread(QCoreApplicationPrivate::mainThread()); | - | ||||||||||||
| 558 | connect(QCoreApplication::instance(), SIGNAL(destroyed()), SLOT(waitForThreadPoolDone()), Qt::DirectConnection); | - | ||||||||||||
| 559 | threadPool.setMaxThreadCount(20); // do up to 20 DNS lookups in parallel | - | ||||||||||||
| 560 | } | - | ||||||||||||
| 561 | - | |||||||||||||
| 562 | QHostInfoLookupManager::~QHostInfoLookupManager() | - | ||||||||||||
| 563 | { | - | ||||||||||||
| 564 | wasDeleted = true; | - | ||||||||||||
| 565 | - | |||||||||||||
| 566 | // don't qDeleteAll currentLookups, the QThreadPool has ownership | - | ||||||||||||
| 567 | clear(); | - | ||||||||||||
| 568 | } | - | ||||||||||||
| 569 | - | |||||||||||||
| 570 | void QHostInfoLookupManager::clear() | - | ||||||||||||
| 571 | { | - | ||||||||||||
| 572 | { | - | ||||||||||||
| 573 | QMutexLocker locker(&mutex); | - | ||||||||||||
| 574 | qDeleteAll(postponedLookups); | - | ||||||||||||
| 575 | qDeleteAll(scheduledLookups); | - | ||||||||||||
| 576 | qDeleteAll(finishedLookups); | - | ||||||||||||
| 577 | postponedLookups.clear(); | - | ||||||||||||
| 578 | scheduledLookups.clear(); | - | ||||||||||||
| 579 | finishedLookups.clear(); | - | ||||||||||||
| 580 | } | - | ||||||||||||
| 581 | - | |||||||||||||
| 582 | threadPool.waitForDone(); | - | ||||||||||||
| 583 | cache.clear(); | - | ||||||||||||
| 584 | } | - | ||||||||||||
| 585 | - | |||||||||||||
| 586 | void QHostInfoLookupManager::work() | - | ||||||||||||
| 587 | { | - | ||||||||||||
| 588 | if (wasDeleted)
| 0-4074 | ||||||||||||
| 589 | return; never executed: return; | 0 | ||||||||||||
| 590 | - | |||||||||||||
| 591 | // goals of this function: | - | ||||||||||||
| 592 | // - launch new lookups via the thread pool | - | ||||||||||||
| 593 | // - make sure only one lookup per host/IP is in progress | - | ||||||||||||
| 594 | - | |||||||||||||
| 595 | QMutexLocker locker(&mutex); | - | ||||||||||||
| 596 | - | |||||||||||||
| 597 | if (!finishedLookups.isEmpty()) {
| 436-3638 | ||||||||||||
| 598 | // remove ID from aborted if it is in there | - | ||||||||||||
| 599 | for (int i = 0; i < finishedLookups.length(); i++) {
| 436 | ||||||||||||
| 600 | abortedLookups.removeAll(finishedLookups.at(i)->id); | - | ||||||||||||
| 601 | } executed 436 times by 19 tests: end of blockExecuted by:
| 436 | ||||||||||||
| 602 | - | |||||||||||||
| 603 | finishedLookups.clear(); | - | ||||||||||||
| 604 | } executed 436 times by 19 tests: end of blockExecuted by:
| 436 | ||||||||||||
| 605 | - | |||||||||||||
| 606 | if (!postponedLookups.isEmpty()) { | - | ||||||||||||
| QMutableListIterator<QHostInfoRunnable*> iterator(postponedLookups); | ||||||||||||||
| while (iterator.hasNext()) {auto isAlreadyRunning = [this](QHostInfoRunnable *postponed = iterator.next(); | ||||||||||||||
| bool alreadyRunning = false; | ||||||||||||||
| forlookup) { | ||||||||||||||
| 607 | return any_of executed 22720 times by 18 tests: (int i = 0; i <currentLookups.length(); i++) {return any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp));Executed by:
executed 22720 times by 18 tests: return any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp));Executed by:
| 22720 | ||||||||||||
| if ( executed 22720 times by 18 tests: cbegin(), currentLookups.atcend(), ToBeLookedUpEquals(i)->toBeLookedUp == postponedlookup->toBeLookedUp) {return any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp));Executed by:
executed 22720 times by 18 tests: return any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp));Executed by:
| ||||||||||||||
| alreadyRunning = true; executed 22720 times by 18 tests: return any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp));Executed by:
| ||||||||||||||
| break; executed 22720 times by 18 tests: return any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp));Executed by:
| ||||||||||||||
| } executed 22720 times by 18 tests: return any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp));Executed by:
| ||||||||||||||
| } executed 22720 times by 18 tests: return any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp));Executed by:
| ||||||||||||||
| if (!alreadyRunning) { executed 22720 times by 18 tests: return any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp));Executed by:
| ||||||||||||||
| iterator executed 22720 times by 18 tests: ));return any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp));Executed by:
executed 22720 times by 18 tests: return any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp));Executed by:
| ||||||||||||||
| 608 | }; | - | ||||||||||||
| 609 | - | |||||||||||||
| 610 | // Transfer any postponed lookups that aren't currently running to the scheduled list, keeping already-running lookups: | - | ||||||||||||
| 611 | postponedLookups.remove(); | - | ||||||||||||
| scheduledLookupserase(separate_if(postponedLookups.prependbegin(), | ||||||||||||||
| 612 | postponedLookups.end(), | - | ||||||||||||
| 613 | postponedLookups.begin(), | - | ||||||||||||
| 614 | std::front_inserter(postponed);scheduledLookups), // prepend! we want to finish it ASAP | - | ||||||||||||
| 615 | } | - | ||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| if (!isAlreadyRunning).first, | ||||||||||||||
| 616 | postponedLookups.end()); | - | ||||||||||||
| 617 | - | |||||||||||||
| 618 | // Unschedule and postpone any that are currently running: | - | ||||||||||||
| 619 | scheduledLookups.isEmpty()) { | - | ||||||||||||
| QMutableListIterator<QHostInfoRunnable*> iteratorerase(scheduledLookups); | ||||||||||||||
| whileseparate_if(iteratorscheduledLookups.hasNext()) { | ||||||||||||||
| QHostInfoRunnable *scheduled = iteratorbegin(), | ||||||||||||||
| 620 | scheduledLookups.next(); | - | ||||||||||||
| forend(), | ||||||||||||||
| 621 | std::back_inserter(postponedLookups), | - | ||||||||||||
| 622 | scheduledLookups.begin(), | - | ||||||||||||
| 623 | isAlreadyRunning).second, | - | ||||||||||||
| 624 | scheduledLookups.end()); | - | ||||||||||||
| 625 | - | |||||||||||||
| 626 | const int iavailableThreads = 0; i <threadPool.maxThreadCount() - currentLookups.size(); | - | ||||||||||||
| 627 | i++) {if (currentLookups.at(i)->toBeLookedUp == scheduled->toBeLookedUpavailableThreads > 0) {
| 0-4074 | ||||||||||||
| 628 | iterator.remove(); | - | ||||||||||||
| postponedLookups.append(scheduled); | ||||||||||||||
| scheduledint readyToStartCount = 0; | ||||||||||||||
| break; | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| ifqMin(scheduled && currentLookupsavailableThreads, scheduledLookups.size() < threadPool()); | ||||||||||||||
| 629 | auto it = scheduledLookups.maxThreadCount())begin(); | - | ||||||||||||
| 630 | while (readyToStartCount--)
| 436-4074 | ||||||||||||
| 631 | // runnable now running in new thread, track this in currentLookups | - | ||||||||||||
| 632 | threadPool.start(scheduled(*it); | - | ||||||||||||
| 633 | iterator.remove();currentLookups.appendpush_back(scheduled); | - | ||||||||||||
| } else { | ||||||||||||||
| continuestd::move(*it)); | ||||||||||||||
| 634 | ++it; | - | ||||||||||||
| 635 | } executed 436 times by 18 tests: end of blockExecuted by:
| 436 | ||||||||||||
| 636 | };scheduledLookups.erase(scheduledLookups.begin(), it); | - | ||||||||||||
| 637 | } executed 4074 times by 19 tests: end of blockExecuted by:
| 4074 | ||||||||||||
| 638 | } executed 4074 times by 19 tests: end of blockExecuted by:
| 4074 | ||||||||||||
| 639 | - | |||||||||||||
| 640 | // called by QHostInfo | - | ||||||||||||
| 641 | void QHostInfoLookupManager::scheduleLookup(QHostInfoRunnable *r) | - | ||||||||||||
| 642 | { | - | ||||||||||||
| 643 | if (wasDeleted) | - | ||||||||||||
| 644 | return; | - | ||||||||||||
| 645 | - | |||||||||||||
| 646 | QMutexLocker locker(&this->mutex); | - | ||||||||||||
| 647 | scheduledLookups.enqueue(r); | - | ||||||||||||
| 648 | work(); | - | ||||||||||||
| 649 | } | - | ||||||||||||
| 650 | - | |||||||||||||
| 651 | // called by QHostInfo | - | ||||||||||||
| 652 | void QHostInfoLookupManager::abortLookup(int id) | - | ||||||||||||
| 653 | { | - | ||||||||||||
| 654 | if (wasDeleted) | - | ||||||||||||
| 655 | return; | - | ||||||||||||
| 656 | - | |||||||||||||
| 657 | QMutexLocker locker(&this->mutex); | - | ||||||||||||
| 658 | - | |||||||||||||
| 659 | // is postponed? delete and return | - | ||||||||||||
| 660 | for (int i = 0; i < postponedLookups.length(); i++) { | - | ||||||||||||
| 661 | if (postponedLookups.at(i)->id == id) { | - | ||||||||||||
| 662 | delete postponedLookups.takeAt(i); | - | ||||||||||||
| 663 | return; | - | ||||||||||||
| 664 | } | - | ||||||||||||
| 665 | } | - | ||||||||||||
| 666 | - | |||||||||||||
| 667 | // is scheduled? delete and return | - | ||||||||||||
| 668 | for (int i = 0; i < scheduledLookups.length(); i++) { | - | ||||||||||||
| 669 | if (scheduledLookups.at(i)->id == id) { | - | ||||||||||||
| 670 | delete scheduledLookups.takeAt(i); | - | ||||||||||||
| 671 | return; | - | ||||||||||||
| 672 | } | - | ||||||||||||
| 673 | } | - | ||||||||||||
| 674 | - | |||||||||||||
| 675 | if (!abortedLookups.contains(id)) | - | ||||||||||||
| 676 | abortedLookups.append(id); | - | ||||||||||||
| 677 | } | - | ||||||||||||
| 678 | - | |||||||||||||
| 679 | // called from QHostInfoRunnable | - | ||||||||||||
| 680 | bool QHostInfoLookupManager::wasAborted(int id) | - | ||||||||||||
| 681 | { | - | ||||||||||||
| 682 | if (wasDeleted) | - | ||||||||||||
| 683 | return true; | - | ||||||||||||
| 684 | - | |||||||||||||
| 685 | QMutexLocker locker(&this->mutex); | - | ||||||||||||
| 686 | return abortedLookups.contains(id); | - | ||||||||||||
| 687 | } | - | ||||||||||||
| 688 | - | |||||||||||||
| 689 | // called from QHostInfoRunnable | - | ||||||||||||
| 690 | void QHostInfoLookupManager::lookupFinished(QHostInfoRunnable *r) | - | ||||||||||||
| 691 | { | - | ||||||||||||
| 692 | if (wasDeleted) | - | ||||||||||||
| 693 | return; | - | ||||||||||||
| 694 | - | |||||||||||||
| 695 | QMutexLocker locker(&this->mutex); | - | ||||||||||||
| 696 | currentLookups.removeOne(r); | - | ||||||||||||
| 697 | finishedLookups.append(r); | - | ||||||||||||
| 698 | work(); | - | ||||||||||||
| 699 | } | - | ||||||||||||
| 700 | - | |||||||||||||
| 701 | // This function returns immediately when we had a result in the cache, else it will later emit a signal | - | ||||||||||||
| 702 | QHostInfo qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id) | - | ||||||||||||
| 703 | { | - | ||||||||||||
| 704 | *valid = false; | - | ||||||||||||
| 705 | *id = -1; | - | ||||||||||||
| 706 | - | |||||||||||||
| 707 | // check cache | - | ||||||||||||
| 708 | QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager(); | - | ||||||||||||
| 709 | if (manager && manager->cache.isEnabled()) { | - | ||||||||||||
| 710 | QHostInfo info = manager->cache.get(name, valid); | - | ||||||||||||
| 711 | if (*valid) { | - | ||||||||||||
| 712 | return info; | - | ||||||||||||
| 713 | } | - | ||||||||||||
| 714 | } | - | ||||||||||||
| 715 | - | |||||||||||||
| 716 | // was not in cache, trigger lookup | - | ||||||||||||
| 717 | *id = QHostInfo::lookupHost(name, receiver, member); | - | ||||||||||||
| 718 | - | |||||||||||||
| 719 | // return empty response, valid==false | - | ||||||||||||
| 720 | return QHostInfo(); | - | ||||||||||||
| 721 | } | - | ||||||||||||
| 722 | - | |||||||||||||
| 723 | void qt_qhostinfo_clear_cache() | - | ||||||||||||
| 724 | { | - | ||||||||||||
| 725 | QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager(); | - | ||||||||||||
| 726 | if (manager) { | - | ||||||||||||
| 727 | manager->clear(); | - | ||||||||||||
| 728 | } | - | ||||||||||||
| 729 | } | - | ||||||||||||
| 730 | - | |||||||||||||
| 731 | #ifdef QT_BUILD_INTERNAL | - | ||||||||||||
| 732 | void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e) | - | ||||||||||||
| 733 | { | - | ||||||||||||
| 734 | QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager(); | - | ||||||||||||
| 735 | if (manager) { | - | ||||||||||||
| 736 | manager->cache.setEnabled(e); | - | ||||||||||||
| 737 | } | - | ||||||||||||
| 738 | } | - | ||||||||||||
| 739 | - | |||||||||||||
| 740 | void qt_qhostinfo_cache_inject(const QString &hostname, const QHostInfo &resolution) | - | ||||||||||||
| 741 | { | - | ||||||||||||
| 742 | QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager(); | - | ||||||||||||
| 743 | if (!manager || !manager->cache.isEnabled()) | - | ||||||||||||
| 744 | return; | - | ||||||||||||
| 745 | - | |||||||||||||
| 746 | manager->cache.put(hostname, resolution); | - | ||||||||||||
| 747 | } | - | ||||||||||||
| 748 | #endif | - | ||||||||||||
| 749 | - | |||||||||||||
| 750 | // cache for 60 seconds | - | ||||||||||||
| 751 | // cache 128 items | - | ||||||||||||
| 752 | QHostInfoCache::QHostInfoCache() : max_age(60), enabled(true), cache(128) | - | ||||||||||||
| 753 | { | - | ||||||||||||
| 754 | #ifdef QT_QHOSTINFO_CACHE_DISABLED_BY_DEFAULT | - | ||||||||||||
| 755 | enabled = false; | - | ||||||||||||
| 756 | #endif | - | ||||||||||||
| 757 | } | - | ||||||||||||
| 758 | - | |||||||||||||
| 759 | bool QHostInfoCache::isEnabled() | - | ||||||||||||
| 760 | { | - | ||||||||||||
| 761 | return enabled; | - | ||||||||||||
| 762 | } | - | ||||||||||||
| 763 | - | |||||||||||||
| 764 | // this function is currently only used for the auto tests | - | ||||||||||||
| 765 | // and not usable by public API | - | ||||||||||||
| 766 | void QHostInfoCache::setEnabled(bool e) | - | ||||||||||||
| 767 | { | - | ||||||||||||
| 768 | enabled = e; | - | ||||||||||||
| 769 | } | - | ||||||||||||
| 770 | - | |||||||||||||
| 771 | - | |||||||||||||
| 772 | QHostInfo QHostInfoCache::get(const QString &name, bool *valid) | - | ||||||||||||
| 773 | { | - | ||||||||||||
| 774 | QMutexLocker locker(&this->mutex); | - | ||||||||||||
| 775 | - | |||||||||||||
| 776 | *valid = false; | - | ||||||||||||
| 777 | if (QHostInfoCacheElement *element = cache.object(name)) { | - | ||||||||||||
| 778 | if (element->age.elapsed() < max_age*1000) | - | ||||||||||||
| 779 | *valid = true; | - | ||||||||||||
| 780 | return element->info; | - | ||||||||||||
| 781 | - | |||||||||||||
| 782 | // FIXME idea: | - | ||||||||||||
| 783 | // if too old but not expired, trigger a new lookup | - | ||||||||||||
| 784 | // to freshen our cache | - | ||||||||||||
| 785 | } | - | ||||||||||||
| 786 | - | |||||||||||||
| 787 | return QHostInfo(); | - | ||||||||||||
| 788 | } | - | ||||||||||||
| 789 | - | |||||||||||||
| 790 | void QHostInfoCache::put(const QString &name, const QHostInfo &info) | - | ||||||||||||
| 791 | { | - | ||||||||||||
| 792 | // if the lookup failed, don't cache | - | ||||||||||||
| 793 | if (info.error() != QHostInfo::NoError) | - | ||||||||||||
| 794 | return; | - | ||||||||||||
| 795 | - | |||||||||||||
| 796 | QHostInfoCacheElement* element = new QHostInfoCacheElement(); | - | ||||||||||||
| 797 | element->info = info; | - | ||||||||||||
| 798 | element->age = QElapsedTimer(); | - | ||||||||||||
| 799 | element->age.start(); | - | ||||||||||||
| 800 | - | |||||||||||||
| 801 | QMutexLocker locker(&this->mutex); | - | ||||||||||||
| 802 | cache.insert(name, element); // cache will take ownership | - | ||||||||||||
| 803 | } | - | ||||||||||||
| 804 | - | |||||||||||||
| 805 | void QHostInfoCache::clear() | - | ||||||||||||
| 806 | { | - | ||||||||||||
| 807 | QMutexLocker locker(&this->mutex); | - | ||||||||||||
| 808 | cache.clear(); | - | ||||||||||||
| 809 | } | - | ||||||||||||
| 810 | - | |||||||||||||
| 811 | QAbstractHostInfoLookupManager* QAbstractHostInfoLookupManager::globalInstance() | - | ||||||||||||
| 812 | { | - | ||||||||||||
| 813 | return theHostInfoLookupManager(); | - | ||||||||||||
| 814 | } | - | ||||||||||||
| 815 | - | |||||||||||||
| 816 | QT_END_NAMESPACE | - | ||||||||||||
| Source code | Switch to Preprocessed file |