| Index: chrome/browser/net/preconnect.cc
|
| ===================================================================
|
| --- chrome/browser/net/preconnect.cc (revision 55024)
|
| +++ chrome/browser/net/preconnect.cc (working copy)
|
| @@ -21,18 +21,22 @@
|
| // 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 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 @@
|
| 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 @@
|
| }
|
| }
|
|
|
| - 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 @@
|
| 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 @@
|
| 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
|
|
|