diff options
-rw-r--r-- | chrome/browser/chromeos/login/login_utils.cc | 8 | ||||
-rw-r--r-- | chrome/browser/net/preconnect.cc | 54 | ||||
-rw-r--r-- | chrome/browser/net/preconnect.h | 48 | ||||
-rw-r--r-- | chrome/browser/net/predictor.cc | 17 | ||||
-rw-r--r-- | net/http/http_request_info.h | 9 | ||||
-rw-r--r-- | net/http/stream_factory.h | 3 | ||||
-rw-r--r-- | net/socket/client_socket_pool_base.cc | 1 |
7 files changed, 67 insertions, 73 deletions
diff --git a/chrome/browser/chromeos/login/login_utils.cc b/chrome/browser/chromeos/login/login_utils.cc index 270de35..d741caf 100644 --- a/chrome/browser/chromeos/login/login_utils.cc +++ b/chrome/browser/chromeos/login/login_utils.cc @@ -416,9 +416,11 @@ class WarmingObserver : public NetworkLibrary::NetworkManagerObserver { // If we're now connected, prewarm the auth url. void OnNetworkManagerChanged(NetworkLibrary* netlib) { if (netlib->Connected()) { + const int kConnectionsNeeded = 1; chrome_browser_net::Preconnect::PreconnectOnUIThread( GURL(GaiaAuthFetcher::kClientLoginUrl), - chrome_browser_net::UrlInfo::EARLY_LOAD_MOTIVATED); + chrome_browser_net::UrlInfo::EARLY_LOAD_MOTIVATED, + kConnectionsNeeded); netlib->RemoveNetworkManagerObserver(this); delete this; } @@ -429,9 +431,11 @@ void LoginUtilsImpl::PrewarmAuthentication() { if (CrosLibrary::Get()->EnsureLoaded()) { NetworkLibrary *network = CrosLibrary::Get()->GetNetworkLibrary(); if (network->Connected()) { + const int kConnectionsNeeded = 1; chrome_browser_net::Preconnect::PreconnectOnUIThread( GURL(GaiaAuthFetcher::kClientLoginUrl), - chrome_browser_net::UrlInfo::EARLY_LOAD_MOTIVATED); + chrome_browser_net::UrlInfo::EARLY_LOAD_MOTIVATED, + kConnectionsNeeded); } else { new WarmingObserver(); } diff --git a/chrome/browser/net/preconnect.cc b/chrome/browser/net/preconnect.cc index 307f20f..5946c85 100644 --- a/chrome/browser/net/preconnect.cc +++ b/chrome/browser/net/preconnect.cc @@ -6,45 +6,44 @@ #include "base/logging.h" #include "base/metrics/histogram.h" -#include "base/string_util.h" #include "chrome/browser/profile.h" #include "chrome/browser/browser_thread.h" #include "chrome/common/net/url_request_context_getter.h" -#include "net/base/host_port_pair.h" #include "net/http/http_network_session.h" -#include "net/http/http_request_info.h" -#include "net/http/http_stream.h" #include "net/http/http_transaction_factory.h" -#include "net/proxy/proxy_service.h" #include "net/url_request/url_request_context.h" namespace chrome_browser_net { // static void Preconnect::PreconnectOnUIThread(const GURL& url, - UrlInfo::ResolutionMotivation motivation) { + UrlInfo::ResolutionMotivation motivation, int count) { // Prewarm connection to Search URL. BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - NewRunnableFunction(Preconnect::PreconnectOnIOThread, url, motivation)); + NewRunnableFunction(Preconnect::PreconnectOnIOThread, url, motivation, + count)); return; } // static void Preconnect::PreconnectOnIOThread(const GURL& url, - UrlInfo::ResolutionMotivation motivation) { + UrlInfo::ResolutionMotivation motivation, int count) { Preconnect* preconnect = new Preconnect(motivation); // TODO(jar): Should I use PostTask for LearnedSubresources to delay the // preconnection a tad? - preconnect->Connect(url); + preconnect->Connect(url, count); } Preconnect::Preconnect(UrlInfo::ResolutionMotivation motivation) - : motivation_(motivation) {} + : motivation_(motivation), + ALLOW_THIS_IN_INITIALIZER_LIST( + io_callback_(this, &Preconnect::OnPreconnectComplete)) {} + Preconnect::~Preconnect() {} -void Preconnect::Connect(const GURL& url) { +void Preconnect::Connect(const GURL& url, int count) { URLRequestContextGetter* getter = Profile::GetDefaultRequestContext(); if (!getter) return; @@ -87,6 +86,7 @@ void Preconnect::Connect(const GURL& url) { request_info_->motivation = net::HttpRequestInfo::PRECONNECT_MOTIVATED; break; case UrlInfo::EARLY_LOAD_MOTIVATED: + request_info_->motivation = net::HttpRequestInfo::EARLY_LOAD_MOTIVATED; break; default: // Other motivations should never happen here. @@ -105,32 +105,16 @@ void Preconnect::Connect(const GURL& url) { proxy_info_.reset(new net::ProxyInfo()); net::StreamFactory* stream_factory = session->http_stream_factory(); - stream_request_.reset( - stream_factory->RequestStream(request_info_.get(), ssl_config_.get(), - proxy_info_.get(), session, this, - net_log_)); -} - -void Preconnect::OnStreamReady(net::HttpStream* stream) { - delete stream; - delete this; -} - -void Preconnect::OnStreamFailed(int status) { - delete this; -} - -void Preconnect::OnCertificateError(int status, const net::SSLInfo& ssl_info) { - delete this; -} - -void Preconnect::OnNeedsProxyAuth(const net::HttpResponseInfo& proxy_response, - net::HttpAuthController* auth_controller) { - delete this; + int rv = stream_factory->PreconnectStreams(count, request_info_.get(), + ssl_config_.get(), + proxy_info_.get(), session, + net_log_, &io_callback_); + if (rv != net::ERR_IO_PENDING) + delete this; } -void Preconnect::OnNeedsClientAuth(net::SSLCertRequestInfo* cert_info) { +void Preconnect::OnPreconnectComplete(int error_code) { delete this; } -} // chrome_browser_net +} // namespace chrome_browser_net diff --git a/chrome/browser/net/preconnect.h b/chrome/browser/net/preconnect.h index 333e0bb..a950167 100644 --- a/chrome/browser/net/preconnect.h +++ b/chrome/browser/net/preconnect.h @@ -9,55 +9,51 @@ #define CHROME_BROWSER_NET_PRECONNECT_H_ #pragma once -#include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "chrome/browser/net/url_info.h" -#include "net/base/host_port_pair.h" +#include "net/base/completion_callback.h" +#include "net/base/net_log.h" #include "net/http/http_request_info.h" #include "net/http/stream_factory.h" -#include "net/socket/client_socket_handle.h" -#include "net/socket/tcp_client_socket_pool.h" -#include "net/url_request/url_request_context.h" namespace net { class ProxyInfo; struct SSLConfig; -} +} // namespace net namespace chrome_browser_net { -class Preconnect : public net::StreamRequest::Delegate { +class Preconnect { public: // Try to preconnect. Typically motivated by OMNIBOX to reach search service. + // |count| may be used to request more than one connection be established in + // parallel. static void PreconnectOnUIThread(const GURL& url, - UrlInfo::ResolutionMotivation motivation); + UrlInfo::ResolutionMotivation motivation, + int count); // Try to preconnect. Typically used by predictor when a subresource probably - // needs a connection. + // needs a connection. |count| may be used to request more than one connection + // be established in parallel. static void PreconnectOnIOThread(const GURL& url, - UrlInfo::ResolutionMotivation motivation); - - // StreamRequestDelegate interface - virtual void OnStreamReady(net::HttpStream* stream); - virtual void OnStreamFailed(int status); - virtual void OnCertificateError(int status, const net::SSLInfo& ssl_info); - virtual void OnNeedsProxyAuth(const net::HttpResponseInfo& proxy_response, - net::HttpAuthController* auth_controller); - virtual void OnNeedsClientAuth(net::SSLCertRequestInfo* cert_info); + UrlInfo::ResolutionMotivation motivation, + int count); private: - friend class base::RefCountedThreadSafe<Preconnect>; - explicit Preconnect(UrlInfo::ResolutionMotivation motivation); virtual ~Preconnect(); - // Request actual connection. - void Connect(const GURL& url); + void OnPreconnectComplete(int error_code); - // Generally either LEARNED_REFERAL_MOTIVATED or OMNIBOX_MOTIVATED to indicate - // why we were trying to do a preconnection. + // Request actual connection, via interface that tags request as needed for + // preconnect only (so that they can be merged with connections needed for + // navigations). + void Connect(const GURL& url, int count); + + // Generally either LEARNED_REFERAL_MOTIVATED, OMNIBOX_MOTIVATED or + // EARLY_LOAD_MOTIVATED to indicate why we were trying to do a preconnection. const UrlInfo::ResolutionMotivation motivation_; // HttpRequestInfo used for connecting. @@ -75,9 +71,11 @@ class Preconnect : public net::StreamRequest::Delegate { // Our preconnect. scoped_ptr<net::StreamRequest> stream_request_; + net::CompletionCallbackImpl<Preconnect> io_callback_; + DISALLOW_COPY_AND_ASSIGN(Preconnect); }; -} // chrome_browser_net +} // namespace chrome_browser_net #endif // CHROME_BROWSER_NET_PRECONNECT_H_ diff --git a/chrome/browser/net/predictor.cc b/chrome/browser/net/predictor.cc index 2c8ce5f..46dcf1f 100644 --- a/chrome/browser/net/predictor.cc +++ b/chrome/browser/net/predictor.cc @@ -5,6 +5,7 @@ #include "chrome/browser/net/predictor.h" #include <algorithm> +#include <cmath> #include <set> #include <sstream> @@ -182,8 +183,9 @@ void Predictor::AnticipateOmniboxUrl(const GURL& url, bool preconnectable) { kMaxSearchKeepaliveSeconds) return; // We've done a preconnect recently. last_omnibox_preconnect_ = now; - - Preconnect::PreconnectOnUIThread(CanonicalizeUrl(url), motivation); + const int kConnectionsNeeded = 1; + Preconnect::PreconnectOnUIThread(CanonicalizeUrl(url), motivation, + kConnectionsNeeded); return; // Skip pre-resolution, since we'll open a connection. } } else { @@ -215,7 +217,9 @@ void Predictor::PreconnectUrlAndSubresources(const GURL& url) { if (preconnect_enabled()) { std::string host = url.HostNoBrackets(); UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED); - Preconnect::PreconnectOnUIThread(CanonicalizeUrl(url), motivation); + const int kConnectionsNeeded = 1; + Preconnect::PreconnectOnUIThread(CanonicalizeUrl(url), motivation, + kConnectionsNeeded); PredictFrameSubresources(url.GetWithEmptyPath()); } } @@ -250,11 +254,12 @@ void Predictor::PrepareFrameSubresources(const GURL& url) { 10, 5000, 50); future_url->second.ReferrerWasObserved(); if (preconnect_enabled_ && - kPreconnectWorthyExpectedValue < connection_expectation) { + connection_expectation > kPreconnectWorthyExpectedValue) { evalution = PRECONNECTION; future_url->second.IncrementPreconnectionCount(); - Preconnect::PreconnectOnIOThread(future_url->first, motivation); - } else if (kDNSPreresolutionWorthyExpectedValue < connection_expectation) { + int count = static_cast<int>(std::ceil(connection_expectation)); + Preconnect::PreconnectOnIOThread(future_url->first, motivation, count); + } else if (connection_expectation > kDNSPreresolutionWorthyExpectedValue) { evalution = PRERESOLUTION; future_url->second.preresolution_increment(); UrlInfo* queued_info = AppendToResolutionQueue(future_url->first, diff --git a/net/http/http_request_info.h b/net/http/http_request_info.h index f740d7c..7c73aa6 100644 --- a/net/http/http_request_info.h +++ b/net/http/http_request_info.h @@ -18,9 +18,12 @@ namespace net { struct HttpRequestInfo { enum RequestMotivation{ // TODO(mbelshe): move these into Client Socket. - PRECONNECT_MOTIVATED, // This request was motivated by a prefetch. - OMNIBOX_MOTIVATED, // This request was motivated by the omnibox. - NORMAL_MOTIVATION // No special motivation associated with the request. + PRECONNECT_MOTIVATED, // Request was motivated by a prefetch. + OMNIBOX_MOTIVATED, // Request was motivated by the omnibox. + NORMAL_MOTIVATION, // No special motivation associated with the request. + EARLY_LOAD_MOTIVATED, // When browser asks a tab to open an URL, this short + // circuits that path (of waiting for the renderer to + // do the URL request), and starts loading ASAP. }; HttpRequestInfo(); diff --git a/net/http/stream_factory.h b/net/http/stream_factory.h index 480df06..94b3cc8 100644 --- a/net/http/stream_factory.h +++ b/net/http/stream_factory.h @@ -122,7 +122,8 @@ class StreamFactory { // Requests that enough connections for |num_streams| be opened. If // ERR_IO_PENDING is returned, |info|, |ssl_config|, and |proxy_info| must - // be kept alive until |callback| is invoked. + // be kept alive until |callback| is invoked. That callback will be given the + // final error code. virtual int PreconnectStreams(int num_streams, const HttpRequestInfo* info, SSLConfig* ssl_config, diff --git a/net/socket/client_socket_pool_base.cc b/net/socket/client_socket_pool_base.cc index 2228729..02ac587 100644 --- a/net/socket/client_socket_pool_base.cc +++ b/net/socket/client_socket_pool_base.cc @@ -233,7 +233,6 @@ void ClientSocketPoolBaseHelper::RequestSockets( DCHECK(!request.handle()); if (num_sockets > max_sockets_per_group_) { - NOTREACHED(); num_sockets = max_sockets_per_group_; } |