Ignore:
Timestamp:
Aug 2, 2010, 9:27:30 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.3 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/network/kernel/qhostinfo.cpp

    r651 r769  
    4545#include "QtCore/qscopedpointer.h"
    4646#include <qabstracteventdispatcher.h>
    47 #include <private/qunicodetables_p.h>
    4847#include <qcoreapplication.h>
    4948#include <qmetaobject.h>
    50 #include <qregexp.h>
    51 #include <private/qnativesocketengine_p.h>
    5249#include <qstringlist.h>
    5350#include <qthread.h>
    54 #include <qtimer.h>
    5551#include <qurl.h>
    5652
     
    112108    To retrieve the name of the local host, use the static
    113109    QHostInfo::localHostName() function.
     110
     111    \note Since Qt 4.6.1 QHostInfo is using multiple threads for DNS lookup
     112    instead of one dedicated DNS thread. This improves performance,
     113    but also changes the order of signal emissions when using lookupHost()
     114    compared to previous versions of Qt.
     115    \note Since Qt 4.6.3 QHostInfo is using a small internal 60 second DNS cache
     116    for performance improvements.
    114117
    115118    \sa QAbstractSocket, {http://www.rfc-editor.org/rfc/rfc3492.txt}{RFC 3492}
     
    182185    result.data()->emitResultsReady(hostInfo);
    183186#else
    184     QHostInfoRunnable* runnable = new QHostInfoRunnable(name, id);
    185     QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection);
    186     theHostInfoLookupManager()->scheduleLookup(runnable);
     187    QHostInfoLookupManager *manager = theHostInfoLookupManager();
     188    if (manager) {
     189        // the application is still alive
     190        if (manager->cache.isEnabled()) {
     191            // check cache first
     192            bool valid = false;
     193            QHostInfo info = manager->cache.get(name, &valid);
     194            if (valid) {
     195                info.setLookupId(id);
     196                QHostInfoResult result;
     197                QObject::connect(&result, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection);
     198                result.emitResultsReady(info);
     199                return id;
     200            }
     201        }
     202        // cache is not enabled or it was not in the cache, do normal lookup
     203        QHostInfoRunnable* runnable = new QHostInfoRunnable(name, id);
     204        QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection);
     205        manager->scheduleLookup(runnable);
     206    }
    187207#endif
    188208
     
    419439    }
    420440
    421     // check cache
    422     // FIXME
    423 
    424     // if not in cache: OS lookup
    425     QHostInfo hostInfo = QHostInfoAgent::fromName(toBeLookedUp);
    426 
    427     // save to cache
    428     // FIXME
     441    QHostInfo hostInfo;
     442
     443    // QHostInfo::lookupHost already checks the cache. However we need to check
     444    // it here too because it might have been cache saved by another QHostInfoRunnable
     445    // in the meanwhile while this QHostInfoRunnable was scheduled but not running
     446    if (manager->cache.isEnabled()) {
     447        // check the cache first
     448        bool valid = false;
     449        hostInfo = manager->cache.get(toBeLookedUp, &valid);
     450        if (!valid) {
     451            // not in cache, we need to do the lookup and store the result in the cache
     452            hostInfo = QHostInfoAgent::fromName(toBeLookedUp);
     453            manager->cache.put(toBeLookedUp, hostInfo);
     454        }
     455    } else {
     456        // cache is not enabled, just do the lookup and continue
     457        hostInfo = QHostInfoAgent::fromName(toBeLookedUp);
     458    }
    429459
    430460    // check aborted again
     
    446476{
    447477    moveToThread(QCoreApplicationPrivate::mainThread());
     478    connect(QCoreApplication::instance(), SIGNAL(destroyed()), SLOT(waitForThreadPoolDone()), Qt::DirectConnection);
    448479    threadPool.setMaxThreadCount(5); // do 5 DNS lookups in parallel
    449480}
     
    452483{
    453484    wasDeleted = true;
     485
     486    // don't qDeleteAll currentLookups, the QThreadPool has ownership
     487    qDeleteAll(postponedLookups);
     488    qDeleteAll(scheduledLookups);
     489    qDeleteAll(finishedLookups);
    454490}
    455491
     
    512548            }
    513549
    514             if (scheduled && threadPool.tryStart(scheduled)) {
     550            if (scheduled && currentLookups.size() < threadPool.maxThreadCount()) {
    515551                // runnable now running in new thread, track this in currentLookups
     552                threadPool.start(scheduled);
    516553                iterator.remove();
    517554                currentLookups.append(scheduled);
    518             } else if (scheduled) {
    519                 // wanted to start, but could not because thread pool is busy
    520                 break;
    521555            } else {
    522556                // was postponed, continue iterating
     
    571605}
    572606
     607// This function returns immediatly when we had a result in the cache, else it will later emit a signal
     608QHostInfo qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id)
     609{
     610    *valid = false;
     611    *id = -1;
     612
     613    // check cache
     614    QHostInfoLookupManager* manager = theHostInfoLookupManager();
     615    if (manager && manager->cache.isEnabled()) {
     616        QHostInfo info = manager->cache.get(name, valid);
     617        if (*valid) {
     618            return info;
     619        }
     620    }
     621
     622    // was not in cache, trigger lookup
     623    *id = QHostInfo::lookupHost(name, receiver, member);
     624
     625    // return empty response, valid==false
     626    return QHostInfo();
     627}
     628
     629void qt_qhostinfo_clear_cache()
     630{
     631    QHostInfoLookupManager* manager = theHostInfoLookupManager();
     632    if (manager) {
     633        manager->cache.clear();
     634    }
     635}
     636
     637void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e)
     638{
     639    QHostInfoLookupManager* manager = theHostInfoLookupManager();
     640    if (manager) {
     641        manager->cache.setEnabled(e);
     642    }
     643}
     644
     645// cache for 60 seconds
     646// cache 64 items
     647QHostInfoCache::QHostInfoCache() : max_age(60), enabled(true), cache(64)
     648{
     649#ifdef QT_QHOSTINFO_CACHE_DISABLED_BY_DEFAULT
     650    enabled = false;
     651#endif
     652}
     653
     654bool QHostInfoCache::isEnabled()
     655{
     656    return enabled;
     657}
     658
     659// this function is currently only used for the auto tests
     660// and not usable by public API
     661void QHostInfoCache::setEnabled(bool e)
     662{
     663    enabled = e;
     664}
     665
     666
     667QHostInfo QHostInfoCache::get(const QString &name, bool *valid)
     668{
     669    QMutexLocker locker(&this->mutex);
     670
     671    *valid = false;
     672    if (cache.contains(name)) {
     673        QHostInfoCacheElement *element = cache.object(name);
     674        if (element->age.elapsed() < max_age*1000)
     675            *valid = true;
     676        return element->info;
     677
     678        // FIXME idea:
     679        // if too old but not expired, trigger a new lookup
     680        // to freshen our cache
     681    }
     682
     683    return QHostInfo();
     684}
     685
     686void QHostInfoCache::put(const QString &name, const QHostInfo &info)
     687{
     688    // if the lookup failed, don't cache
     689    if (info.error() != QHostInfo::NoError)
     690        return;
     691
     692    QHostInfoCacheElement* element = new QHostInfoCacheElement();
     693    element->info = info;
     694    element->age = QTime();
     695    element->age.start();
     696
     697    QMutexLocker locker(&this->mutex);
     698    cache.insert(name, element); // cache will take ownership
     699}
     700
     701void QHostInfoCache::clear()
     702{
     703    QMutexLocker locker(&this->mutex);
     704    cache.clear();
     705}
     706
    573707#endif // QT_NO_THREAD
    574708
Note: See TracChangeset for help on using the changeset viewer.