diff options
author | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-06 07:10:24 +0000 |
---|---|---|
committer | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-06 07:10:24 +0000 |
commit | 9008c86f2a99b112300ef7833d35f2ff1696a88a (patch) | |
tree | 9ba3e6a50b61f76612f3db42b18e5f10ae6f364a /chrome/browser/net/preconnect.cc | |
parent | 6a054ffaae82f5ac8d6b876d7c85f0d87d892e42 (diff) | |
download | chromium_src-9008c86f2a99b112300ef7833d35f2ff1696a88a.zip chromium_src-9008c86f2a99b112300ef7833d35f2ff1696a88a.tar.gz chromium_src-9008c86f2a99b112300ef7833d35f2ff1696a88a.tar.bz2 |
Reland 54771 (and 54795) To enable TCP Preconnection by default
I pulled out the code to update the socket connectivity stats.
I added defensive code which should preclude the crash that
was reported on the stability bot.
I added a second call to update the stats from
~ClientSocketHandle to ensure that we updated the
related ClientSocket when we are torn down.
As noted in the original checkin:
Enable speculative preconnection by default
Added histogram to track preconnection utilization (vs waste).
BUG=42694
r=mbelshe
Review URL: http://codereview.chromium.org/3050040
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@55197 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/net/preconnect.cc')
-rw-r--r-- | chrome/browser/net/preconnect.cc | 64 |
1 files changed, 43 insertions, 21 deletions
diff --git a/chrome/browser/net/preconnect.cc b/chrome/browser/net/preconnect.cc index e8038ff..3872d2a 100644 --- a/chrome/browser/net/preconnect.cc +++ b/chrome/browser/net/preconnect.cc @@ -21,18 +21,22 @@ namespace chrome_browser_net { // static bool Preconnect::preconnect_despite_proxy_ = false; -// We will deliberately leak this singular instance, which is used only for -// callbacks. -// static -Preconnect* Preconnect::callback_instance_; + +Preconnect::~Preconnect() { + if (!handle_.is_initialized()) + return; + DCHECK(motivation_ == UrlInfo::LEARNED_REFERAL_MOTIVATED || + motivation_ == UrlInfo::OMNIBOX_MOTIVATED); + if (motivation_ == UrlInfo::OMNIBOX_MOTIVATED) + handle_.socket()->SetOmniboxSpeculation(); + else + handle_.socket()->SetSubresourceSpeculation(); + handle_.Reset(); +} // static void Preconnect::PreconnectOnUIThread(const GURL& url, UrlInfo::ResolutionMotivation motivation) { - // Try to do connection warming for this search provider. - URLRequestContextGetter* getter = Profile::GetDefaultRequestContext(); - if (!getter) - return; // Prewarm connection to Search URL. ChromeThread::PostTask( ChromeThread::IO, @@ -57,6 +61,13 @@ static void HistogramPreconnectStatus(ProxyStatus status) { // static void Preconnect::PreconnectOnIOThread(const GURL& url, UrlInfo::ResolutionMotivation motivation) { + scoped_refptr<Preconnect> preconnect = new Preconnect(motivation); + // TODO(jar): Should I use PostTask for LearnedSubresources to delay the + // preconnection a tad? + preconnect->Connect(url); +} + +void Preconnect::Connect(const GURL& url) { URLRequestContextGetter* getter = Profile::GetDefaultRequestContext(); if (!getter) return; @@ -64,6 +75,9 @@ void Preconnect::PreconnectOnIOThread(const GURL& url, LOG(DFATAL) << "This must be run only on the IO thread."; return; } + + AddRef(); // Stay alive until socket is available. + URLRequestContext* context = getter->GetURLRequestContext(); if (preconnect_despite_proxy_) { @@ -86,16 +100,12 @@ void Preconnect::PreconnectOnIOThread(const GURL& url, } } - UMA_HISTOGRAM_ENUMERATION("Net.PreconnectMotivation", motivation, + UMA_HISTOGRAM_ENUMERATION("Net.PreconnectMotivation", motivation_, UrlInfo::MAX_MOTIVATED); net::HttpTransactionFactory* factory = context->http_transaction_factory(); net::HttpNetworkSession* session = factory->GetSession(); - net::ClientSocketHandle handle; - if (!callback_instance_) - callback_instance_ = new Preconnect; - scoped_refptr<net::TCPSocketParams> tcp_params = new net::TCPSocketParams(url.host(), url.EffectiveIntPort(), net::LOW, GURL(), false); @@ -103,6 +113,19 @@ void Preconnect::PreconnectOnIOThread(const GURL& url, net::HostPortPair endpoint(url.host(), url.EffectiveIntPort()); std::string group_name = endpoint.ToString(); + // It almost doesn't matter whether we use net::LOWEST or net::HIGHEST + // priority here, as we won't make a request, and will surrender the created + // socket to the pool as soon as we can. However, we would like to mark the + // speculative socket as such, and IF we use a net::LOWEST priority, and if + // a navigation asked for a socket (after us) then it would get our socket, + // and we'd get its later-arriving socket, which might make us record that + // the speculation didn't help :-/. By using net::HIGHEST, we ensure that + // a socket is given to us if "we asked first" and this allows us to mark it + // as speculative, and better detect stats (if it gets used). + // TODO(jar): histogram to see how often we accidentally use a previously- + // unused socket, when a previously used socket was available. + net::RequestPriority priority = net::HIGHEST; + if (url.SchemeIs("https")) { group_name = StringPrintf("ssl/%s", group_name.c_str()); @@ -120,21 +143,20 @@ void Preconnect::PreconnectOnIOThread(const GURL& url, const scoped_refptr<net::SSLClientSocketPool>& pool = session->ssl_socket_pool(); - handle.Init(group_name, ssl_params, net::LOWEST, callback_instance_, pool, - net::BoundNetLog()); - handle.Reset(); + handle_.Init(group_name, ssl_params, priority, this, pool, + net::BoundNetLog()); return; } const scoped_refptr<net::TCPClientSocketPool>& pool = session->tcp_socket_pool(); - handle.Init(group_name, tcp_params, net::LOWEST, callback_instance_, pool, - net::BoundNetLog()); - handle.Reset(); + handle_.Init(group_name, tcp_params, priority, this, pool, + net::BoundNetLog()); } void Preconnect::RunWithParams(const Tuple1<int>& params) { - // This will rarely be called, as we reset the connection just after creating. - NOTREACHED(); + if (params.a < 0 && handle_.socket()) + handle_.socket()->Disconnect(); + Release(); } } // chrome_browser_net |