Chromium Code Reviews| Index: chrome/browser/net/predictor.cc |
| diff --git a/chrome/browser/net/predictor.cc b/chrome/browser/net/predictor.cc |
| index 658223c1dc4df7b607f73ce2586e67a957b2014c..f7a56635d2adf30ec5015dbf2761b3ce09929297 100644 |
| --- a/chrome/browser/net/predictor.cc |
| +++ b/chrome/browser/net/predictor.cc |
| @@ -12,6 +12,7 @@ |
| #include <utility> |
| #include "base/bind.h" |
| +#include "base/callback.h" |
| #include "base/compiler_specific.h" |
| #include "base/containers/mru_cache.h" |
| #include "base/location.h" |
| @@ -111,7 +112,8 @@ Predictor::Predictor(bool preconnect_enabled, bool predictor_enabled) |
| referrers_(kMaxReferrers), |
| observer_(nullptr), |
| timed_cache_(new TimedCache(base::TimeDelta::FromSeconds( |
| - kMaxUnusedSocketLifetimeSecondsWithoutAGet))) { |
| + kMaxUnusedSocketLifetimeSecondsWithoutAGet))), |
| + ui_weak_factory_(new base::WeakPtrFactory<Predictor>(this)) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| } |
| @@ -131,8 +133,10 @@ Predictor* Predictor::CreatePredictor(bool preconnect_enabled, |
| void Predictor::RegisterProfilePrefs( |
| user_prefs::PrefRegistrySyncable* registry) { |
| - registry->RegisterListPref(prefs::kDnsPrefetchingStartupList); |
| - registry->RegisterListPref(prefs::kDnsPrefetchingHostReferralList); |
| + registry->RegisterListPref(prefs::kDnsPrefetchingStartupList, |
| + PrefRegistry::LOSSY_PREF); |
| + registry->RegisterListPref(prefs::kDnsPrefetchingHostReferralList, |
| + PrefRegistry::LOSSY_PREF); |
| } |
| // --------------------- Start UI methods. ------------------------------------ |
| @@ -310,9 +314,9 @@ std::vector<GURL> Predictor::GetPredictedUrlListAtStartup( |
| void Predictor::DiscardAllResultsAndClearPrefsOnUIThread() { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| - BrowserThread::PostTask( |
| - BrowserThread::IO, FROM_HERE, |
| - base::Bind(&Predictor::DiscardAllResults, weak_factory_->GetWeakPtr())); |
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| + base::Bind(&Predictor::DiscardAllResults, |
| + io_weak_factory_->GetWeakPtr())); |
| ClearPrefsOnUIThread(); |
| } |
| @@ -334,6 +338,7 @@ void Predictor::set_max_parallel_resolves(size_t max_parallel_resolves) { |
| void Predictor::ShutdownOnUIThread() { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + ui_weak_factory_->InvalidateWeakPtrs(); |
| BrowserThread::PostTask( |
| BrowserThread::IO, |
| FROM_HERE, |
| @@ -604,11 +609,8 @@ void Predictor::FinalizeInitializationOnIOThread( |
| proxy_service_ = context->proxy_service(); |
| // base::WeakPtrFactory instances need to be created and destroyed |
| - // on the same thread. The predictor lives on the IO thread and will die |
| - // from there so now that we're on the IO thread we need to properly |
| - // initialize the base::WeakPtrFactory. |
| - // TODO(groby): Check if WeakPtrFactory has the same constraint. |
| - weak_factory_.reset(new base::WeakPtrFactory<Predictor>(this)); |
| + // on the same thread. Initialize the IO thread weak factory now. |
| + io_weak_factory_.reset(new base::WeakPtrFactory<Predictor>(this)); |
| // Prefetch these hostnames on startup. |
| DnsPrefetchMotivatedList(startup_urls, UrlInfo::STARTUP_LIST_MOTIVATED); |
| @@ -676,68 +678,48 @@ void Predictor::DnsPrefetchMotivatedList( |
| // Functions to handle saving of hostnames from one session to the next, to |
| // expedite startup times. |
| -static void SaveDnsPrefetchStateForNextStartupOnIOThread( |
| - base::ListValue* startup_list, |
| - base::ListValue* referral_list, |
| - base::WaitableEvent* completion, |
| - Predictor* predictor) { |
| - DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - |
| - if (nullptr == predictor) { |
| - completion->Signal(); |
| - return; |
| - } |
| - predictor->SaveDnsPrefetchStateForNextStartup(startup_list, referral_list, |
| - completion); |
| -} |
| - |
| void Predictor::SaveStateForNextStartup() { |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| if (!predictor_enabled_) |
| return; |
| if (!CanPreresolveAndPreconnect()) |
| return; |
| - base::WaitableEvent completion( |
| - base::WaitableEvent::ResetPolicy::MANUAL, |
| - base::WaitableEvent::InitialState::NOT_SIGNALED); |
| + std::unique_ptr<base::ListValue> startup_list( |
| + user_prefs_->GetList(prefs::kDnsPrefetchingStartupList)->DeepCopy()); |
|
mmenke
2016/08/01 15:11:20
I'm not following this code. WriteDnsPrefetchStat
Bernhard Bauer
2016/08/01 15:18:52
Huh, you're right! Which makes me wonder why this
Charlie Harrison
2016/08/01 15:20:03
Yeah, good catch Matt. I think we can just initial
mmenke
2016/08/01 15:27:48
Or could just create them on the IO thread. Guess
Charlie Harrison
2016/08/01 15:34:23
Given the double hop, I think I prefer initializin
|
| + std::unique_ptr<base::ListValue> referral_list( |
| + user_prefs_->GetList(prefs::kDnsPrefetchingHostReferralList)->DeepCopy()); |
| + // Get raw pointers to pass to the first task. Ownership of the unique_ptrs |
| + // will be passed to the reply task. |
| + base::ListValue* startup_list_raw = startup_list.get(); |
| + base::ListValue* referral_list_raw = referral_list.get(); |
| - ListPrefUpdate update_startup_list(user_prefs_, |
| - prefs::kDnsPrefetchingStartupList); |
| - ListPrefUpdate update_referral_list(user_prefs_, |
| - prefs::kDnsPrefetchingHostReferralList); |
| - if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| - SaveDnsPrefetchStateForNextStartupOnIOThread(update_startup_list.Get(), |
| - update_referral_list.Get(), |
| - &completion, this); |
| - } else { |
| - bool posted = BrowserThread::PostTask( |
| - BrowserThread::IO, FROM_HERE, |
| - base::Bind(&SaveDnsPrefetchStateForNextStartupOnIOThread, |
| - update_startup_list.Get(), update_referral_list.Get(), |
| - &completion, this)); |
| - |
| - // TODO(jar): Synchronous waiting for the IO thread is a potential source |
| - // to deadlocks and should be investigated. See http://crbug.com/78451. |
| - DCHECK(posted); |
| - if (posted) { |
| - // http://crbug.com/124954 |
| - base::ThreadRestrictions::ScopedAllowWait allow_wait; |
| - completion.Wait(); |
| - } |
| - } |
| + BrowserThread::PostTaskAndReply( |
| + BrowserThread::IO, FROM_HERE, |
| + base::Bind(&Predictor::WriteDnsPrefetchState, |
| + io_weak_factory_->GetWeakPtr(), startup_list_raw, |
| + referral_list_raw), |
| + base::Bind(&Predictor::UpdatePrefsOnUIThread, |
| + ui_weak_factory_->GetWeakPtr(), |
| + base::Passed(std::move(startup_list)), |
| + base::Passed(std::move(referral_list)))); |
| } |
| -void Predictor::SaveDnsPrefetchStateForNextStartup( |
| - base::ListValue* startup_list, |
| - base::ListValue* referral_list, |
| - base::WaitableEvent* completion) { |
| +void Predictor::UpdatePrefsOnUIThread( |
| + std::unique_ptr<base::ListValue> startup_list, |
| + std::unique_ptr<base::ListValue> referral_list) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + user_prefs_->Set(prefs::kDnsPrefetchingStartupList, *startup_list); |
| + user_prefs_->Set(prefs::kDnsPrefetchingHostReferralList, *referral_list); |
| +} |
| + |
| +void Predictor::WriteDnsPrefetchState(base::ListValue* startup_list, |
| + base::ListValue* referral_list) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| if (initial_observer_.get()) |
| initial_observer_->GetInitialDnsResolutionList(startup_list); |
| SerializeReferrers(referral_list); |
| - |
| - completion->Signal(); |
| } |
| void Predictor::PreconnectUrl(const GURL& url, |
| @@ -1032,7 +1014,7 @@ void Predictor::StartSomeQueuedResolutions() { |
| int status = |
| content::PreresolveUrl(profile_io_data_->GetResourceContext(), url, |
| base::Bind(&Predictor::OnLookupFinished, |
| - weak_factory_->GetWeakPtr(), url)); |
| + io_weak_factory_->GetWeakPtr(), url)); |
| if (status == net::ERR_IO_PENDING) { |
| // Will complete asynchronously. |
| num_pending_lookups_++; |