Changeset 769 for trunk/src/network/kernel/qhostinfo.cpp
- Timestamp:
- Aug 2, 2010, 9:27:30 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.6.3 (added) merged: 768 /branches/vendor/nokia/qt/current merged: 767 /branches/vendor/nokia/qt/4.6.2 removed
- Property svn:mergeinfo changed
-
trunk/src/network/kernel/qhostinfo.cpp
r651 r769 45 45 #include "QtCore/qscopedpointer.h" 46 46 #include <qabstracteventdispatcher.h> 47 #include <private/qunicodetables_p.h>48 47 #include <qcoreapplication.h> 49 48 #include <qmetaobject.h> 50 #include <qregexp.h>51 #include <private/qnativesocketengine_p.h>52 49 #include <qstringlist.h> 53 50 #include <qthread.h> 54 #include <qtimer.h>55 51 #include <qurl.h> 56 52 … … 112 108 To retrieve the name of the local host, use the static 113 109 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. 114 117 115 118 \sa QAbstractSocket, {http://www.rfc-editor.org/rfc/rfc3492.txt}{RFC 3492} … … 182 185 result.data()->emitResultsReady(hostInfo); 183 186 #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 } 187 207 #endif 188 208 … … 419 439 } 420 440 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 } 429 459 430 460 // check aborted again … … 446 476 { 447 477 moveToThread(QCoreApplicationPrivate::mainThread()); 478 connect(QCoreApplication::instance(), SIGNAL(destroyed()), SLOT(waitForThreadPoolDone()), Qt::DirectConnection); 448 479 threadPool.setMaxThreadCount(5); // do 5 DNS lookups in parallel 449 480 } … … 452 483 { 453 484 wasDeleted = true; 485 486 // don't qDeleteAll currentLookups, the QThreadPool has ownership 487 qDeleteAll(postponedLookups); 488 qDeleteAll(scheduledLookups); 489 qDeleteAll(finishedLookups); 454 490 } 455 491 … … 512 548 } 513 549 514 if (scheduled && threadPool.tryStart(scheduled)) {550 if (scheduled && currentLookups.size() < threadPool.maxThreadCount()) { 515 551 // runnable now running in new thread, track this in currentLookups 552 threadPool.start(scheduled); 516 553 iterator.remove(); 517 554 currentLookups.append(scheduled); 518 } else if (scheduled) {519 // wanted to start, but could not because thread pool is busy520 break;521 555 } else { 522 556 // was postponed, continue iterating … … 571 605 } 572 606 607 // This function returns immediatly when we had a result in the cache, else it will later emit a signal 608 QHostInfo 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 629 void qt_qhostinfo_clear_cache() 630 { 631 QHostInfoLookupManager* manager = theHostInfoLookupManager(); 632 if (manager) { 633 manager->cache.clear(); 634 } 635 } 636 637 void 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 647 QHostInfoCache::QHostInfoCache() : max_age(60), enabled(true), cache(64) 648 { 649 #ifdef QT_QHOSTINFO_CACHE_DISABLED_BY_DEFAULT 650 enabled = false; 651 #endif 652 } 653 654 bool 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 661 void QHostInfoCache::setEnabled(bool e) 662 { 663 enabled = e; 664 } 665 666 667 QHostInfo 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 686 void 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 701 void QHostInfoCache::clear() 702 { 703 QMutexLocker locker(&this->mutex); 704 cache.clear(); 705 } 706 573 707 #endif // QT_NO_THREAD 574 708
Note:
See TracChangeset
for help on using the changeset viewer.