| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/net/dns_global.h" | 5 #include "chrome/browser/net/dns_global.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/singleton.h" | 10 #include "base/singleton.h" |
| 11 #include "base/stats_counters.h" | 11 #include "base/stats_counters.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "base/thread.h" | 13 #include "base/thread.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "chrome/browser/browser.h" | 15 #include "chrome/browser/browser.h" |
| 16 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
| 17 #include "chrome/browser/net/dns_host_info.h" | 17 #include "chrome/browser/net/dns_host_info.h" |
| 18 #include "chrome/browser/net/referrer.h" | 18 #include "chrome/browser/net/referrer.h" |
| 19 #include "chrome/browser/profile.h" | 19 #include "chrome/browser/profile.h" |
| 20 #include "chrome/browser/session_startup_pref.h" | 20 #include "chrome/browser/session_startup_pref.h" |
| 21 #include "chrome/common/notification_registrar.h" | 21 #include "chrome/common/notification_registrar.h" |
| 22 #include "chrome/common/notification_service.h" | 22 #include "chrome/common/notification_service.h" |
| 23 #include "chrome/common/pref_names.h" | 23 #include "chrome/common/pref_names.h" |
| 24 #include "chrome/common/pref_service.h" | 24 #include "chrome/common/pref_service.h" |
| 25 #include "net/base/host_resolver.h" | 25 #include "net/base/host_resolver.h" |
| 26 | 26 |
| 27 using base::Time; |
| 27 using base::TimeDelta; | 28 using base::TimeDelta; |
| 28 | 29 |
| 29 namespace chrome_browser_net { | 30 namespace chrome_browser_net { |
| 30 | 31 |
| 31 static void DiscardAllPrefetchState(); | 32 static void DiscardAllPrefetchState(); |
| 32 static void DnsMotivatedPrefetch(const std::string& hostname, | 33 static void DnsMotivatedPrefetch(const std::string& hostname, |
| 33 DnsHostInfo::ResolutionMotivation motivation); | 34 DnsHostInfo::ResolutionMotivation motivation); |
| 34 static void DnsPrefetchMotivatedList( | 35 static void DnsPrefetchMotivatedList( |
| 35 const NameList& hostnames, | 36 const NameList& hostnames, |
| 36 DnsHostInfo::ResolutionMotivation motivation); | 37 DnsHostInfo::ResolutionMotivation motivation); |
| 37 | 38 |
| 38 // static | 39 // static |
| 39 const size_t DnsPrefetcherInit::kMaxConcurrentLookups = 8; | 40 const size_t DnsPrefetcherInit::kMaxConcurrentLookups = 8; |
| 40 | 41 |
| 42 // static |
| 43 const int DnsPrefetcherInit::kMaxQueueingDelayMs = 1000; |
| 44 |
| 41 // Host resolver shared by DNS prefetcher, and the main URLRequestContext. | 45 // Host resolver shared by DNS prefetcher, and the main URLRequestContext. |
| 42 static net::HostResolver* global_host_resolver = NULL; | 46 static net::HostResolver* global_host_resolver = NULL; |
| 43 | 47 |
| 44 //------------------------------------------------------------------------------ | 48 //------------------------------------------------------------------------------ |
| 45 // This section contains all the globally accessable API entry points for the | 49 // This section contains all the globally accessable API entry points for the |
| 46 // DNS Prefetching feature. | 50 // DNS Prefetching feature. |
| 47 //------------------------------------------------------------------------------ | 51 //------------------------------------------------------------------------------ |
| 48 | 52 |
| 49 // Status of prefetch feature, controlling whether any prefetching is done. | 53 // Status of prefetch feature, controlling whether any prefetching is done. |
| 50 static bool dns_prefetch_enabled = true; | 54 static bool dns_prefetch_enabled = true; |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 | 278 |
| 275 // static | 279 // static |
| 276 void PrefetchObserver::SaveStartupListAsPref(PrefService* local_state) { | 280 void PrefetchObserver::SaveStartupListAsPref(PrefService* local_state) { |
| 277 ListValue* startup_list = | 281 ListValue* startup_list = |
| 278 local_state->GetMutableList(prefs::kDnsStartupPrefetchList); | 282 local_state->GetMutableList(prefs::kDnsStartupPrefetchList); |
| 279 | 283 |
| 280 DCHECK(startup_list); | 284 DCHECK(startup_list); |
| 281 if (!startup_list) | 285 if (!startup_list) |
| 282 return; | 286 return; |
| 283 startup_list->Clear(); | 287 startup_list->Clear(); |
| 284 DCHECK(startup_list->GetSize() == 0); | 288 DCHECK_EQ(0u, startup_list->GetSize()); |
| 285 AutoLock auto_lock(*lock); | 289 AutoLock auto_lock(*lock); |
| 286 for (Results::iterator it = first_resolutions->begin(); | 290 for (Results::iterator it = first_resolutions->begin(); |
| 287 it != first_resolutions->end(); | 291 it != first_resolutions->end(); |
| 288 it++) { | 292 it++) { |
| 289 const std::string hostname = it->first; | 293 const std::string hostname = it->first; |
| 290 startup_list->Append(Value::CreateStringValue(hostname)); | 294 startup_list->Append(Value::CreateStringValue(hostname)); |
| 291 } | 295 } |
| 292 } | 296 } |
| 293 | 297 |
| 294 // static | 298 // static |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 ++count_off_the_record_windows_; | 343 ++count_off_the_record_windows_; |
| 340 } | 344 } |
| 341 OnTheRecord(false); | 345 OnTheRecord(false); |
| 342 break; | 346 break; |
| 343 | 347 |
| 344 case NotificationType::BROWSER_CLOSED: | 348 case NotificationType::BROWSER_CLOSED: |
| 345 if (!Source<Browser>(source)->profile()->IsOffTheRecord()) | 349 if (!Source<Browser>(source)->profile()->IsOffTheRecord()) |
| 346 break; // Ignore ordinary windows. | 350 break; // Ignore ordinary windows. |
| 347 { | 351 { |
| 348 AutoLock lock(lock_); | 352 AutoLock lock(lock_); |
| 349 DCHECK(0 < count_off_the_record_windows_); | 353 DCHECK_LT(0, count_off_the_record_windows_); |
| 350 if (0 >= count_off_the_record_windows_) // Defensive coding. | 354 if (0 >= count_off_the_record_windows_) // Defensive coding. |
| 351 break; | 355 break; |
| 352 if (--count_off_the_record_windows_) | 356 if (--count_off_the_record_windows_) |
| 353 break; // Still some windows are incognito. | 357 break; // Still some windows are incognito. |
| 354 } // Release lock. | 358 } // Release lock. |
| 355 OnTheRecord(true); | 359 OnTheRecord(true); |
| 356 break; | 360 break; |
| 357 | 361 |
| 358 default: | 362 default: |
| 359 break; | 363 break; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 | 402 |
| 399 //------------------------------------------------------------------------------ | 403 //------------------------------------------------------------------------------ |
| 400 // This section intializes and tears down global DNS prefetch services. | 404 // This section intializes and tears down global DNS prefetch services. |
| 401 //------------------------------------------------------------------------------ | 405 //------------------------------------------------------------------------------ |
| 402 | 406 |
| 403 // Note: We have explicit permission to create the following global static | 407 // Note: We have explicit permission to create the following global static |
| 404 // object (in opposition to Google style rules). By making it a static, we | 408 // object (in opposition to Google style rules). By making it a static, we |
| 405 // can ensure its deletion. | 409 // can ensure its deletion. |
| 406 static PrefetchObserver dns_resolution_observer; | 410 static PrefetchObserver dns_resolution_observer; |
| 407 | 411 |
| 408 void InitDnsPrefetch(size_t max_concurrent, PrefService* user_prefs) { | 412 void InitDnsPrefetch(TimeDelta max_queue_delay, size_t max_concurrent, |
| 413 PrefService* user_prefs) { |
| 409 // Use a large shutdown time so that UI tests (that instigate lookups, and | 414 // Use a large shutdown time so that UI tests (that instigate lookups, and |
| 410 // then try to shutdown the browser) don't instigate the CHECK about | 415 // then try to shutdown the browser) don't instigate the CHECK about |
| 411 // "some slaves have not finished" | 416 // "some slaves have not finished" |
| 412 const TimeDelta kAllowableShutdownTime(TimeDelta::FromSeconds(10)); | 417 const TimeDelta kAllowableShutdownTime(TimeDelta::FromSeconds(10)); |
| 413 DCHECK(NULL == dns_master); | 418 DCHECK(NULL == dns_master); |
| 414 if (!dns_master) { | 419 if (!dns_master) { |
| 415 // Have the DnsMaster issue resolve requests through a global HostResolver | 420 // Have the DnsMaster issue resolve requests through a global HostResolver |
| 416 // that is shared by the main URLRequestContext, and lives on the IO thread. | 421 // that is shared by the main URLRequestContext, and lives on the IO thread. |
| 417 dns_master = new DnsMaster(GetGlobalHostResolver(), | 422 dns_master = new DnsMaster(GetGlobalHostResolver(), |
| 418 g_browser_process->io_thread()->message_loop(), | 423 g_browser_process->io_thread()->message_loop(), |
| 419 max_concurrent); | 424 max_queue_delay, max_concurrent); |
| 420 dns_master->AddRef(); | 425 dns_master->AddRef(); |
| 421 // We did the initialization, so we should prime the pump, and set up | 426 // We did the initialization, so we should prime the pump, and set up |
| 422 // the DNS resolution system to run. | 427 // the DNS resolution system to run. |
| 423 Singleton<OffTheRecordObserver>::get()->Register(); | 428 Singleton<OffTheRecordObserver>::get()->Register(); |
| 424 | 429 |
| 425 if (user_prefs) { | 430 if (user_prefs) { |
| 426 bool enabled = user_prefs->GetBoolean(prefs::kDnsPrefetchingEnabled); | 431 bool enabled = user_prefs->GetBoolean(prefs::kDnsPrefetchingEnabled); |
| 427 EnableDnsPrefetch(enabled); | 432 EnableDnsPrefetch(enabled); |
| 428 } | 433 } |
| 429 | 434 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 local_state->GetMutableList(prefs::kDnsHostReferralList); | 553 local_state->GetMutableList(prefs::kDnsHostReferralList); |
| 549 dns_master->DeserializeReferrers(*referral_list); | 554 dns_master->DeserializeReferrers(*referral_list); |
| 550 } | 555 } |
| 551 | 556 |
| 552 void TrimSubresourceReferrers() { | 557 void TrimSubresourceReferrers() { |
| 553 if (NULL == dns_master) | 558 if (NULL == dns_master) |
| 554 return; | 559 return; |
| 555 dns_master->TrimReferrers(); | 560 dns_master->TrimReferrers(); |
| 556 } | 561 } |
| 557 | 562 |
| 563 //------------------------------------------------------------------------------ |
| 564 // Methods for the helper class that is used to startup and teardown the whole |
| 565 // DNS prefetch system. |
| 566 |
| 567 DnsPrefetcherInit::DnsPrefetcherInit(PrefService* user_prefs, |
| 568 PrefService* local_state) { |
| 569 // Set up a field trial to see what disabling DNS pre-resolution does to |
| 570 // latency of page loads. |
| 571 FieldTrial::Probability kDivisor = 100; |
| 572 // For each option (i.e., non-default), we have a fixed probability. |
| 573 FieldTrial::Probability kProbabilityPerGroup = 10; // 10% probability. |
| 574 |
| 575 trial_ = new FieldTrial("DnsImpact", kDivisor); |
| 576 |
| 577 // First option is to disable prefetching completely. |
| 578 int disabled_prefetch = trial_->AppendGroup("_disabled_prefetch", |
| 579 kProbabilityPerGroup); |
| 580 // Set parallel prefetch limit to 4 instead of default 8. |
| 581 int parallel_4_prefetch = trial_->AppendGroup("_parallel_4_prefetch", |
| 582 kProbabilityPerGroup); |
| 583 // Set congestion detection at 500ms, rather than the 1 second default. |
| 584 int max_500ms_prefetch = trial_->AppendGroup("_max_500ms_prefetch_queue", |
| 585 kProbabilityPerGroup); |
| 586 // Set congestion detection at 2 seconds instead of the 1 second default. |
| 587 int max_2s_prefetch = trial_->AppendGroup("_max_2s_prefetch_queue", |
| 588 kProbabilityPerGroup); |
| 589 |
| 590 if (trial_->group() != disabled_prefetch) { |
| 591 // Initialize the DNS prefetch system. |
| 592 |
| 593 size_t max_concurrent = kMaxConcurrentLookups; |
| 594 |
| 595 int max_queueing_delay_ms = kMaxQueueingDelayMs; |
| 596 |
| 597 if (trial_->group() == parallel_4_prefetch) |
| 598 max_concurrent = 4; |
| 599 else if (trial_->group() == max_500ms_prefetch) |
| 600 max_queueing_delay_ms = 500; |
| 601 else if (trial_->group() == max_2s_prefetch) |
| 602 max_queueing_delay_ms = 2000; |
| 603 |
| 604 TimeDelta max_queueing_delay( |
| 605 TimeDelta::FromMilliseconds(max_queueing_delay_ms)); |
| 606 |
| 607 DCHECK(!dns_master); |
| 608 InitDnsPrefetch(max_queueing_delay, max_concurrent, user_prefs); |
| 609 DCHECK(dns_master); // Will be checked in destructor. |
| 610 chrome_browser_net::DnsPrefetchHostNamesAtStartup(user_prefs, local_state); |
| 611 chrome_browser_net::RestoreSubresourceReferrers(local_state); |
| 612 } |
| 613 } |
| 614 |
| 615 DnsPrefetcherInit::~DnsPrefetcherInit() { |
| 616 if (dns_master) |
| 617 FreeDnsPrefetchResources(); |
| 618 } |
| 619 |
| 558 } // namespace chrome_browser_net | 620 } // namespace chrome_browser_net |
| 621 |
| OLD | NEW |