summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-07 03:53:02 +0000
committerthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-07 03:53:02 +0000
commitd1a3edbfce9a5e91e1fed6bc1ac857ec1cc91089 (patch)
treec76b35ab5a541e2d7d06f15a65e540a9da58424d
parentfc3ff06f4687604132f7727e4d8bb2e1dd3b6934 (diff)
downloadchromium_src-d1a3edbfce9a5e91e1fed6bc1ac857ec1cc91089.zip
chromium_src-d1a3edbfce9a5e91e1fed6bc1ac857ec1cc91089.tar.gz
chromium_src-d1a3edbfce9a5e91e1fed6bc1ac857ec1cc91089.tar.bz2
Revert 113338 - Revert 113315 (speculative revert for http://crbug.com/106657)
- Save pipelining capabilities for the most used hosts between sessions. BUG=None TEST=unit_tests Review URL: http://codereview.chromium.org/8770035 TBR=simonjam@chromium.org Review URL: http://codereview.chromium.org/8833003 TBR=thakis@chromium.org Review URL: http://codereview.chromium.org/8832003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113341 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/memory/mru_cache.h4
-rw-r--r--chrome/browser/net/http_server_properties_manager.cc98
-rw-r--r--chrome/browser/net/http_server_properties_manager.h18
-rw-r--r--chrome/browser/net/http_server_properties_manager_unittest.cc61
-rw-r--r--net/http/http_pipelined_host.h18
-rw-r--r--net/http/http_pipelined_host_capability.h24
-rw-r--r--net/http/http_pipelined_host_impl.cc28
-rw-r--r--net/http/http_pipelined_host_impl.h5
-rw-r--r--net/http/http_pipelined_host_impl_unittest.cc22
-rw-r--r--net/http/http_pipelined_host_pool.cc42
-rw-r--r--net/http/http_pipelined_host_pool.h14
-rw-r--r--net/http/http_pipelined_host_pool_unittest.cc43
-rw-r--r--net/http/http_server_properties.h14
-rw-r--r--net/http/http_server_properties_impl.cc63
-rw-r--r--net/http/http_server_properties_impl.h27
-rw-r--r--net/http/http_stream_factory_impl.cc3
-rw-r--r--net/net.gyp1
17 files changed, 373 insertions, 112 deletions
diff --git a/base/memory/mru_cache.h b/base/memory/mru_cache.h
index 434e592..29db3cf 100644
--- a/base/memory/mru_cache.h
+++ b/base/memory/mru_cache.h
@@ -181,12 +181,12 @@ class MRUCacheBase {
// can keep them as you insert or delete things (as long as you don't delete
// the one you are pointing to) and they will still be valid.
iterator begin() { return ordering_.begin(); }
- const_iterator begin() const { ordering_.begin(); }
+ const_iterator begin() const { return ordering_.begin(); }
iterator end() { return ordering_.end(); }
const_iterator end() const { return ordering_.end(); }
reverse_iterator rbegin() { return ordering_.rbegin(); }
- const_reverse_iterator rbegin() const { ordering_.rbegin(); }
+ const_reverse_iterator rbegin() const { return ordering_.rbegin(); }
reverse_iterator rend() { return ordering_.rend(); }
const_reverse_iterator rend() const { return ordering_.rend(); }
diff --git a/chrome/browser/net/http_server_properties_manager.cc b/chrome/browser/net/http_server_properties_manager.cc
index dad1876..390e87d 100644
--- a/chrome/browser/net/http_server_properties_manager.cc
+++ b/chrome/browser/net/http_server_properties_manager.cc
@@ -171,6 +171,33 @@ HttpServerPropertiesManager::spdy_settings_map() const {
return http_server_properties_impl_->spdy_settings_map();
}
+net::HttpPipelinedHostCapability
+HttpServerPropertiesManager::GetPipelineCapability(
+ const net::HostPortPair& origin) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ return http_server_properties_impl_->GetPipelineCapability(origin);
+}
+
+void HttpServerPropertiesManager::SetPipelineCapability(
+ const net::HostPortPair& origin,
+ net::HttpPipelinedHostCapability capability) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ http_server_properties_impl_->SetPipelineCapability(origin, capability);
+ ScheduleUpdatePrefsOnIO();
+}
+
+void HttpServerPropertiesManager::ClearPipelineCapabilities() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ http_server_properties_impl_->ClearPipelineCapabilities();
+ ScheduleUpdatePrefsOnIO();
+}
+
+net::PipelineCapabilityMap
+HttpServerPropertiesManager::GetPipelineCapabilityMap() const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ return http_server_properties_impl_->GetPipelineCapabilityMap();
+}
+
//
// Update the HttpServerPropertiesImpl's cache with data from preferences.
//
@@ -207,6 +234,9 @@ void HttpServerPropertiesManager::UpdateCacheFromPrefsOnUI() {
net::AlternateProtocolMap* alternate_protocol_map =
new net::AlternateProtocolMap;
+ net::PipelineCapabilityMap* pipeline_capability_map =
+ new net::PipelineCapabilityMap;
+
const base::DictionaryValue& http_server_properties_dict =
*pref_service_->GetDictionary(prefs::kHttpServerProperties);
for (base::DictionaryValue::key_iterator it =
@@ -281,6 +311,14 @@ void HttpServerPropertiesManager::UpdateCacheFromPrefsOnUI() {
(*spdy_settings_map)[server] = spdy_settings;
}
+ int pipeline_capability = net::PIPELINE_UNKNOWN;
+ if ((server_pref_dict->GetInteger(
+ "pipeline_capability", &pipeline_capability)) &&
+ pipeline_capability != net::PIPELINE_UNKNOWN) {
+ (*pipeline_capability_map)[server] =
+ static_cast<net::HttpPipelinedHostCapability>(pipeline_capability);
+ }
+
// Get alternate_protocol server.
DCHECK(!ContainsKey(*alternate_protocol_map, server));
base::DictionaryValue* port_alternate_protocol_dict = NULL;
@@ -323,13 +361,15 @@ void HttpServerPropertiesManager::UpdateCacheFromPrefsOnUI() {
base::Unretained(this),
base::Owned(spdy_servers),
base::Owned(spdy_settings_map),
- base::Owned(alternate_protocol_map)));
+ base::Owned(alternate_protocol_map),
+ base::Owned(pipeline_capability_map)));
}
void HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO(
StringVector* spdy_servers,
net::SpdySettingsMap* spdy_settings_map,
- net::AlternateProtocolMap* alternate_protocol_map) {
+ net::AlternateProtocolMap* alternate_protocol_map,
+ net::PipelineCapabilityMap* pipeline_capability_map) {
// Preferences have the master data because admins might have pushed new
// preferences. Update the cached data with new data from preferences.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -344,6 +384,9 @@ void HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO(
// preferences.
http_server_properties_impl_->InitializeAlternateProtocolServers(
alternate_protocol_map);
+
+ http_server_properties_impl_->InitializePipelineCapabilities(
+ pipeline_capability_map);
}
@@ -381,6 +424,11 @@ void HttpServerPropertiesManager::UpdatePrefsFromCacheOnIO() {
*alternate_protocol_map =
http_server_properties_impl_->alternate_protocol_map();
+ net::PipelineCapabilityMap* pipeline_capability_map =
+ new net::PipelineCapabilityMap;
+ *pipeline_capability_map =
+ http_server_properties_impl_->GetPipelineCapabilityMap();
+
// Update the preferences on the UI thread.
BrowserThread::PostTask(
BrowserThread::UI,
@@ -389,34 +437,39 @@ void HttpServerPropertiesManager::UpdatePrefsFromCacheOnIO() {
ui_weak_ptr_,
base::Owned(spdy_server_list),
base::Owned(spdy_settings_map),
- base::Owned(alternate_protocol_map)));
+ base::Owned(alternate_protocol_map),
+ base::Owned(pipeline_capability_map)));
}
-// A local or temporary data structure to hold supports_spdy, SpdySettings and
-// PortAlternateProtocolPair preferences for a server. This is used only in
-// UpdatePrefsOnUI.
+// A local or temporary data structure to hold |supports_spdy|, SpdySettings,
+// PortAlternateProtocolPair, and |pipeline_capability| preferences for a
+// server. This is used only in UpdatePrefsOnUI.
struct ServerPref {
ServerPref()
: supports_spdy(false),
settings(NULL),
- alternate_protocol(NULL) {
+ alternate_protocol(NULL),
+ pipeline_capability(net::PIPELINE_UNKNOWN) {
}
ServerPref(bool supports_spdy,
const spdy::SpdySettings* settings,
const net::PortAlternateProtocolPair* alternate_protocol)
: supports_spdy(supports_spdy),
settings(settings),
- alternate_protocol(alternate_protocol) {
+ alternate_protocol(alternate_protocol),
+ pipeline_capability(net::PIPELINE_UNKNOWN) {
}
bool supports_spdy;
const spdy::SpdySettings* settings;
const net::PortAlternateProtocolPair* alternate_protocol;
+ net::HttpPipelinedHostCapability pipeline_capability;
};
void HttpServerPropertiesManager::UpdatePrefsOnUI(
base::ListValue* spdy_server_list,
net::SpdySettingsMap* spdy_settings_map,
- net::AlternateProtocolMap* alternate_protocol_map) {
+ net::AlternateProtocolMap* alternate_protocol_map,
+ net::PipelineCapabilityMap* pipeline_capability_map) {
typedef std::map<net::HostPortPair, ServerPref> ServerPrefMap;
ServerPrefMap server_pref_map;
@@ -476,6 +529,23 @@ void HttpServerPropertiesManager::UpdatePrefsOnUI(
}
}
+ for (net::PipelineCapabilityMap::const_iterator map_it =
+ pipeline_capability_map->begin();
+ map_it != pipeline_capability_map->end(); ++map_it) {
+ const net::HostPortPair& server = map_it->first;
+ const net::HttpPipelinedHostCapability& pipeline_capability =
+ map_it->second;
+
+ ServerPrefMap::iterator it = server_pref_map.find(server);
+ if (it == server_pref_map.end()) {
+ ServerPref server_pref;
+ server_pref.pipeline_capability = pipeline_capability;
+ server_pref_map[server] = server_pref;
+ } else {
+ it->second.pipeline_capability = pipeline_capability;
+ }
+ }
+
// Persist the prefs::kHttpServerProperties.
base::DictionaryValue http_server_properties_dict;
for (ServerPrefMap::const_iterator map_it =
@@ -518,8 +588,14 @@ void HttpServerPropertiesManager::UpdatePrefsOnUI(
server_pref_dict->SetWithoutPathExpansion(
"alternate_protocol", port_alternate_protocol_dict);
}
- http_server_properties_dict.SetWithoutPathExpansion(
- server.ToString(), server_pref_dict);
+
+ if (server_pref.pipeline_capability != net::PIPELINE_UNKNOWN) {
+ server_pref_dict->SetInteger("pipeline_capability",
+ server_pref.pipeline_capability);
+ }
+
+ http_server_properties_dict.SetWithoutPathExpansion(server.ToString(),
+ server_pref_dict);
}
setting_prefs_ = true;
diff --git a/chrome/browser/net/http_server_properties_manager.h b/chrome/browser/net/http_server_properties_manager.h
index 78c595e..f2e75fd 100644
--- a/chrome/browser/net/http_server_properties_manager.h
+++ b/chrome/browser/net/http_server_properties_manager.h
@@ -17,6 +17,7 @@
#include "chrome/browser/prefs/pref_change_registrar.h"
#include "content/public/browser/notification_observer.h"
#include "net/base/host_port_pair.h"
+#include "net/http/http_pipelined_host_capability.h"
#include "net/http/http_server_properties.h"
#include "net/http/http_server_properties_impl.h"
@@ -122,6 +123,17 @@ class HttpServerPropertiesManager
// Returns all SpdySettings mappings.
virtual const net::SpdySettingsMap& spdy_settings_map() const OVERRIDE;
+ virtual net::HttpPipelinedHostCapability GetPipelineCapability(
+ const net::HostPortPair& origin) OVERRIDE;
+
+ virtual void SetPipelineCapability(
+ const net::HostPortPair& origin,
+ net::HttpPipelinedHostCapability capability) OVERRIDE;
+
+ virtual void ClearPipelineCapabilities() OVERRIDE;
+
+ virtual net::PipelineCapabilityMap GetPipelineCapabilityMap() const OVERRIDE;
+
protected:
// --------------------
// SPDY related methods
@@ -145,7 +157,8 @@ class HttpServerPropertiesManager
void UpdateCacheFromPrefsOnIO(
std::vector<std::string>* spdy_servers,
net::SpdySettingsMap* spdy_settings_map,
- net::AlternateProtocolMap* alternate_protocol_map);
+ net::AlternateProtocolMap* alternate_protocol_map,
+ net::PipelineCapabilityMap* pipeline_capability_map);
// These are used to delay updating the preferences when cached data in
// |http_server_properties_impl_| is changing, and execute only one update per
@@ -167,7 +180,8 @@ class HttpServerPropertiesManager
void UpdatePrefsOnUI(
base::ListValue* spdy_server_list,
net::SpdySettingsMap* spdy_settings_map,
- net::AlternateProtocolMap* alternate_protocol_map);
+ net::AlternateProtocolMap* alternate_protocol_map,
+ net::PipelineCapabilityMap* pipeline_capability_map);
private:
// Callback for preference changes.
diff --git a/chrome/browser/net/http_server_properties_manager_unittest.cc b/chrome/browser/net/http_server_properties_manager_unittest.cc
index 98cb86b..c2b3d90 100644
--- a/chrome/browser/net/http_server_properties_manager_unittest.cc
+++ b/chrome/browser/net/http_server_properties_manager_unittest.cc
@@ -60,14 +60,16 @@ class TestingHttpServerPropertiesManager : public HttpServerPropertiesManager {
MOCK_METHOD0(UpdateCacheFromPrefsOnUI, void());
MOCK_METHOD0(UpdatePrefsFromCacheOnIO, void());
- MOCK_METHOD3(UpdateCacheFromPrefsOnIO,
+ MOCK_METHOD4(UpdateCacheFromPrefsOnIO,
void(std::vector<std::string>* spdy_servers,
net::SpdySettingsMap* spdy_settings_map,
- net::AlternateProtocolMap* alternate_protocol_map));
- MOCK_METHOD3(UpdatePrefsOnUI,
+ net::AlternateProtocolMap* alternate_protocol_map,
+ net::PipelineCapabilityMap* pipeline_capability_map));
+ MOCK_METHOD4(UpdatePrefsOnUI,
void(base::ListValue* spdy_server_list,
net::SpdySettingsMap* spdy_settings_map,
- net::AlternateProtocolMap* alternate_protocol_map));
+ net::AlternateProtocolMap* alternate_protocol_map,
+ net::PipelineCapabilityMap* pipeline_capability_map));
private:
DISALLOW_COPY_AND_ASSIGN(TestingHttpServerPropertiesManager);
@@ -152,6 +154,9 @@ TEST_F(HttpServerPropertiesManagerTest,
server_pref_dict->SetWithoutPathExpansion(
"alternate_protocol", alternate_protocol);
+ // Set pipeline capability for www.google.com:80.
+ server_pref_dict->SetInteger("pipeline_capability", net::PIPELINE_CAPABLE);
+
// Set the server preference for www.google.com:80.
base::DictionaryValue* http_server_properties_dict =
new base::DictionaryValue;
@@ -181,6 +186,9 @@ TEST_F(HttpServerPropertiesManagerTest,
server_pref_dict1->SetWithoutPathExpansion(
"alternate_protocol", alternate_protocol1);
+ // Set pipelining capability for mail.google.com:80
+ server_pref_dict1->SetInteger("pipeline_capability", net::PIPELINE_INCAPABLE);
+
// Set the server preference for mail.google.com:80.
http_server_properties_dict->SetWithoutPathExpansion(
"mail.google.com:80", server_pref_dict1);
@@ -238,6 +246,14 @@ TEST_F(HttpServerPropertiesManagerTest,
net::HostPortPair::FromString("mail.google.com:80"));
EXPECT_EQ(444, port_alternate_protocol.port);
EXPECT_EQ(net::NPN_SPDY_2, port_alternate_protocol.protocol);
+
+ // Verify pipeline capability.
+ EXPECT_EQ(net::PIPELINE_CAPABLE,
+ http_server_props_manager_->GetPipelineCapability(
+ net::HostPortPair::FromString("www.google.com:80")));
+ EXPECT_EQ(net::PIPELINE_INCAPABLE,
+ http_server_props_manager_->GetPipelineCapability(
+ net::HostPortPair::FromString("mail.google.com:80")));
}
TEST_F(HttpServerPropertiesManagerTest, SupportsSpdy) {
@@ -306,6 +322,33 @@ TEST_F(HttpServerPropertiesManagerTest, HasAlternateProtocol) {
EXPECT_EQ(net::NPN_SPDY_2, port_alternate_protocol.protocol);
}
+TEST_F(HttpServerPropertiesManagerTest, PipelineCapability) {
+ ExpectPrefsUpdate();
+
+ net::HostPortPair known_pipeliner("pipeline.com", 8080);
+ net::HostPortPair bad_pipeliner("wordpress.com", 80);
+ EXPECT_EQ(net::PIPELINE_UNKNOWN,
+ http_server_props_manager_->GetPipelineCapability(known_pipeliner));
+ EXPECT_EQ(net::PIPELINE_UNKNOWN,
+ http_server_props_manager_->GetPipelineCapability(bad_pipeliner));
+
+ // Post an update task to the IO thread. SetPipelineCapability calls
+ // ScheduleUpdatePrefsOnIO.
+ http_server_props_manager_->SetPipelineCapability(known_pipeliner,
+ net::PIPELINE_CAPABLE);
+ http_server_props_manager_->SetPipelineCapability(bad_pipeliner,
+ net::PIPELINE_INCAPABLE);
+
+ // Run the task.
+ loop_.RunAllPending();
+
+ EXPECT_EQ(net::PIPELINE_CAPABLE,
+ http_server_props_manager_->GetPipelineCapability(known_pipeliner));
+ EXPECT_EQ(net::PIPELINE_INCAPABLE,
+ http_server_props_manager_->GetPipelineCapability(bad_pipeliner));
+ Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
+}
+
TEST_F(HttpServerPropertiesManagerTest, Clear) {
ExpectPrefsUpdate();
@@ -321,6 +364,10 @@ TEST_F(HttpServerPropertiesManagerTest, Clear) {
spdy_settings.push_back(std::make_pair(id1, 31337));
http_server_props_manager_->SetSpdySettings(spdy_server_mail, spdy_settings);
+ net::HostPortPair known_pipeliner("pipeline.com", 8080);
+ http_server_props_manager_->SetPipelineCapability(known_pipeliner,
+ net::PIPELINE_CAPABLE);
+
// Run the task.
loop_.RunAllPending();
@@ -337,6 +384,9 @@ TEST_F(HttpServerPropertiesManagerTest, Clear) {
EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, id1_ret.flags());
EXPECT_EQ(31337U, spdy_setting1_ret.second);
+ EXPECT_EQ(net::PIPELINE_CAPABLE,
+ http_server_props_manager_->GetPipelineCapability(known_pipeliner));
+
Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
ExpectPrefsUpdate();
@@ -354,6 +404,9 @@ TEST_F(HttpServerPropertiesManagerTest, Clear) {
http_server_props_manager_->GetSpdySettings(spdy_server_mail);
EXPECT_EQ(0U, spdy_settings1_ret.size());
+ EXPECT_EQ(net::PIPELINE_UNKNOWN,
+ http_server_props_manager_->GetPipelineCapability(known_pipeliner));
+
Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
}
diff --git a/net/http/http_pipelined_host.h b/net/http/http_pipelined_host.h
index c368313..711b98d 100644
--- a/net/http/http_pipelined_host.h
+++ b/net/http/http_pipelined_host.h
@@ -6,14 +6,15 @@
#define NET_HTTP_HTTP_PIPELINED_HOST_H_
#pragma once
-#include "net/base/host_port_pair.h"
#include "net/base/net_export.h"
#include "net/http/http_pipelined_connection.h"
+#include "net/http/http_pipelined_host_capability.h"
namespace net {
class BoundNetLog;
class ClientSocketHandle;
+class HostPortPair;
class HttpPipelinedStream;
class ProxyInfo;
struct SSLConfig;
@@ -23,14 +24,6 @@ struct SSLConfig;
// assigns requests to the least loaded pipelined connection.
class NET_EXPORT_PRIVATE HttpPipelinedHost {
public:
- enum Capability {
- UNKNOWN,
- INCAPABLE,
- CAPABLE,
- PROBABLY_CAPABLE, // We are using pipelining, but haven't processed enough
- // requests to record this host as known to be capable.
- };
-
class Delegate {
public:
// Called when a pipelined host has no outstanding requests on any of its
@@ -42,8 +35,9 @@ class NET_EXPORT_PRIVATE HttpPipelinedHost {
virtual void OnHostHasAdditionalCapacity(HttpPipelinedHost* host) = 0;
// Called when a host determines if pipelining can be used.
- virtual void OnHostDeterminedCapability(HttpPipelinedHost* host,
- Capability capability) = 0;
+ virtual void OnHostDeterminedCapability(
+ HttpPipelinedHost* host,
+ HttpPipelinedHostCapability capability) = 0;
};
class Factory {
@@ -54,7 +48,7 @@ class NET_EXPORT_PRIVATE HttpPipelinedHost {
virtual HttpPipelinedHost* CreateNewHost(
Delegate* delegate, const HostPortPair& origin,
HttpPipelinedConnection::Factory* factory,
- Capability capability) = 0;
+ HttpPipelinedHostCapability capability) = 0;
};
virtual ~HttpPipelinedHost() {}
diff --git a/net/http/http_pipelined_host_capability.h b/net/http/http_pipelined_host_capability.h
new file mode 100644
index 0000000..2c44cd3
--- /dev/null
+++ b/net/http/http_pipelined_host_capability.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_HTTP_HTTP_PIPELINED_HOST_CAPABILITY_H_
+#define NET_HTTP_HTTP_PIPELINED_HOST_CAPABILITY_H_
+#pragma once
+
+namespace net {
+
+// These values are serialized in Preferences. Do not change these values and
+// only add new ones at the end.
+enum HttpPipelinedHostCapability {
+ PIPELINE_UNKNOWN = 0,
+ PIPELINE_INCAPABLE = 1,
+ PIPELINE_CAPABLE = 2,
+ PIPELINE_PROBABLY_CAPABLE = 3, // We are using pipelining, but haven't
+ // processed enough requests to record this
+ // host as known to be capable.
+};
+
+} // namespace net
+
+#endif // NET_HTTP_HTTP_PIPELINED_HOST_CAPABILITY_H_
diff --git a/net/http/http_pipelined_host_impl.cc b/net/http/http_pipelined_host_impl.cc
index d554fe1..6ca759e 100644
--- a/net/http/http_pipelined_host_impl.cc
+++ b/net/http/http_pipelined_host_impl.cc
@@ -34,7 +34,7 @@ HttpPipelinedHostImpl::HttpPipelinedHostImpl(
HttpPipelinedHost::Delegate* delegate,
const HostPortPair& origin,
HttpPipelinedConnection::Factory* factory,
- Capability capability)
+ HttpPipelinedHostCapability capability)
: delegate_(delegate),
origin_(origin),
factory_(factory),
@@ -54,7 +54,7 @@ HttpPipelinedStream* HttpPipelinedHostImpl::CreateStreamOnNewPipeline(
const ProxyInfo& used_proxy_info,
const BoundNetLog& net_log,
bool was_npn_negotiated) {
- if (capability_ == INCAPABLE) {
+ if (capability_ == PIPELINE_INCAPABLE) {
return NULL;
}
HttpPipelinedConnection* pipeline = factory_->CreateNewPipeline(
@@ -124,21 +124,21 @@ void HttpPipelinedHostImpl::OnPipelineFeedback(
switch (feedback) {
case HttpPipelinedConnection::OK:
++pipelines_[pipeline].num_successes;
- if (capability_ == UNKNOWN) {
- capability_ = PROBABLY_CAPABLE;
+ if (capability_ == PIPELINE_UNKNOWN) {
+ capability_ = PIPELINE_PROBABLY_CAPABLE;
NotifyAllPipelinesHaveCapacity();
- } else if (capability_ == PROBABLY_CAPABLE &&
+ } else if (capability_ == PIPELINE_PROBABLY_CAPABLE &&
pipelines_[pipeline].num_successes >=
kNumKnownSuccessesThreshold) {
- capability_ = CAPABLE;
- delegate_->OnHostDeterminedCapability(this, CAPABLE);
+ capability_ = PIPELINE_CAPABLE;
+ delegate_->OnHostDeterminedCapability(this, PIPELINE_CAPABLE);
}
break;
case HttpPipelinedConnection::PIPELINE_SOCKET_ERROR:
case HttpPipelinedConnection::OLD_HTTP_VERSION:
- capability_ = INCAPABLE;
- delegate_->OnHostDeterminedCapability(this, INCAPABLE);
+ capability_ = PIPELINE_INCAPABLE;
+ delegate_->OnHostDeterminedCapability(this, PIPELINE_INCAPABLE);
break;
case HttpPipelinedConnection::MUST_CLOSE_CONNECTION:
@@ -149,15 +149,15 @@ void HttpPipelinedHostImpl::OnPipelineFeedback(
int HttpPipelinedHostImpl::GetPipelineCapacity() const {
int capacity = 0;
switch (capability_) {
- case CAPABLE:
- case PROBABLY_CAPABLE:
+ case PIPELINE_CAPABLE:
+ case PIPELINE_PROBABLY_CAPABLE:
capacity = max_pipeline_depth();
break;
- case INCAPABLE:
+ case PIPELINE_INCAPABLE:
CHECK(false);
- case UNKNOWN:
+ case PIPELINE_UNKNOWN:
capacity = 1;
break;
@@ -169,7 +169,7 @@ int HttpPipelinedHostImpl::GetPipelineCapacity() const {
bool HttpPipelinedHostImpl::CanPipelineAcceptRequests(
HttpPipelinedConnection* pipeline) const {
- return capability_ != INCAPABLE &&
+ return capability_ != PIPELINE_INCAPABLE &&
pipeline->usable() &&
pipeline->active() &&
pipeline->depth() < GetPipelineCapacity();
diff --git a/net/http/http_pipelined_host_impl.h b/net/http/http_pipelined_host_impl.h
index c1d745c..1286d69 100644
--- a/net/http/http_pipelined_host_impl.h
+++ b/net/http/http_pipelined_host_impl.h
@@ -15,6 +15,7 @@
#include "net/base/net_export.h"
#include "net/http/http_pipelined_connection.h"
#include "net/http/http_pipelined_host.h"
+#include "net/http/http_pipelined_host_capability.h"
namespace net {
@@ -34,7 +35,7 @@ class NET_EXPORT_PRIVATE HttpPipelinedHostImpl
HttpPipelinedHostImpl(HttpPipelinedHost::Delegate* delegate,
const HostPortPair& origin,
HttpPipelinedConnection::Factory* factory,
- Capability capability);
+ HttpPipelinedHostCapability capability);
virtual ~HttpPipelinedHostImpl();
// HttpPipelinedHost interface
@@ -98,7 +99,7 @@ class NET_EXPORT_PRIVATE HttpPipelinedHostImpl
const HostPortPair origin_;
PipelineInfoMap pipelines_;
scoped_ptr<HttpPipelinedConnection::Factory> factory_;
- Capability capability_;
+ HttpPipelinedHostCapability capability_;
DISALLOW_COPY_AND_ASSIGN(HttpPipelinedHostImpl);
};
diff --git a/net/http/http_pipelined_host_impl_unittest.cc b/net/http/http_pipelined_host_impl_unittest.cc
index ed7d722..3eace82 100644
--- a/net/http/http_pipelined_host_impl_unittest.cc
+++ b/net/http/http_pipelined_host_impl_unittest.cc
@@ -32,7 +32,7 @@ class MockHostDelegate : public HttpPipelinedHost::Delegate {
MOCK_METHOD1(OnHostHasAdditionalCapacity, void(HttpPipelinedHost* host));
MOCK_METHOD2(OnHostDeterminedCapability,
void(HttpPipelinedHost* host,
- HttpPipelinedHost::Capability capability));
+ HttpPipelinedHostCapability capability));
};
class MockPipelineFactory : public HttpPipelinedConnection::Factory {
@@ -83,10 +83,10 @@ class HttpPipelinedHostImplTest : public testing::Test {
: origin_("host", 123),
factory_(new MockPipelineFactory), // Owned by host_.
host_(new HttpPipelinedHostImpl(&delegate_, origin_, factory_,
- HttpPipelinedHost::CAPABLE)) {
+ PIPELINE_CAPABLE)) {
}
- void SetCapability(HttpPipelinedHost::Capability capability) {
+ void SetCapability(HttpPipelinedHostCapability capability) {
factory_ = new MockPipelineFactory;
host_.reset(new HttpPipelinedHostImpl(
&delegate_, origin_, factory_, capability));
@@ -200,7 +200,7 @@ TEST_F(HttpPipelinedHostImplTest, PicksLeastLoadedPipeline) {
}
TEST_F(HttpPipelinedHostImplTest, OpensUpOnPipelineSuccess) {
- SetCapability(HttpPipelinedHost::UNKNOWN);
+ SetCapability(PIPELINE_UNKNOWN);
MockPipeline* pipeline = AddTestPipeline(1, true, true);
EXPECT_EQ(NULL, host_->CreateStreamOnExistingPipeline());
@@ -219,7 +219,7 @@ TEST_F(HttpPipelinedHostImplTest, OpensUpOnPipelineSuccess) {
}
TEST_F(HttpPipelinedHostImplTest, OpensAllPipelinesOnPipelineSuccess) {
- SetCapability(HttpPipelinedHost::UNKNOWN);
+ SetCapability(PIPELINE_UNKNOWN);
MockPipeline* pipeline1 = AddTestPipeline(1, false, true);
MockPipeline* pipeline2 = AddTestPipeline(1, true, true);
@@ -240,15 +240,14 @@ TEST_F(HttpPipelinedHostImplTest, OpensAllPipelinesOnPipelineSuccess) {
}
TEST_F(HttpPipelinedHostImplTest, ShutsDownOnOldVersion) {
- SetCapability(HttpPipelinedHost::UNKNOWN);
+ SetCapability(PIPELINE_UNKNOWN);
MockPipeline* pipeline = AddTestPipeline(1, true, true);
EXPECT_EQ(NULL, host_->CreateStreamOnExistingPipeline());
EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
.Times(0);
EXPECT_CALL(delegate_,
- OnHostDeterminedCapability(host_.get(),
- HttpPipelinedHost::INCAPABLE))
+ OnHostDeterminedCapability(host_.get(), PIPELINE_INCAPABLE))
.Times(1);
host_->OnPipelineFeedback(pipeline,
HttpPipelinedConnection::OLD_HTTP_VERSION);
@@ -259,7 +258,7 @@ TEST_F(HttpPipelinedHostImplTest, ShutsDownOnOldVersion) {
}
TEST_F(HttpPipelinedHostImplTest, ConnectionCloseHasNoEffect) {
- SetCapability(HttpPipelinedHost::UNKNOWN);
+ SetCapability(PIPELINE_UNKNOWN);
MockPipeline* pipeline = AddTestPipeline(1, true, true);
EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
@@ -276,14 +275,13 @@ TEST_F(HttpPipelinedHostImplTest, ConnectionCloseHasNoEffect) {
}
TEST_F(HttpPipelinedHostImplTest, SuccessesLeadToCapable) {
- SetCapability(HttpPipelinedHost::UNKNOWN);
+ SetCapability(PIPELINE_UNKNOWN);
MockPipeline* pipeline = AddTestPipeline(1, true, true);
EXPECT_CALL(delegate_, OnHostHasAdditionalCapacity(host_.get()))
.Times(1);
EXPECT_CALL(delegate_,
- OnHostDeterminedCapability(host_.get(),
- HttpPipelinedHost::CAPABLE))
+ OnHostDeterminedCapability(host_.get(), PIPELINE_CAPABLE))
.Times(1);
host_->OnPipelineFeedback(pipeline, HttpPipelinedConnection::OK);
diff --git a/net/http/http_pipelined_host_pool.cc b/net/http/http_pipelined_host_pool.cc
index fa705a0..71eb0ae 100644
--- a/net/http/http_pipelined_host_pool.cc
+++ b/net/http/http_pipelined_host_pool.cc
@@ -6,31 +6,29 @@
#include "base/logging.h"
#include "base/stl_util.h"
+#include "net/http/http_pipelined_host_capability.h"
#include "net/http/http_pipelined_host_impl.h"
+#include "net/http/http_server_properties.h"
namespace net {
-// TODO(simonjam): Run experiments with different values of this to see what
-// value is good at avoiding evictions without eating too much memory. Until
-// then, this is just a bad guess.
-static const int kNumHostsToRemember = 200;
-
class HttpPipelinedHostImplFactory : public HttpPipelinedHost::Factory {
public:
virtual HttpPipelinedHost* CreateNewHost(
HttpPipelinedHost::Delegate* delegate, const HostPortPair& origin,
HttpPipelinedConnection::Factory* factory,
- HttpPipelinedHost::Capability capability) OVERRIDE {
+ HttpPipelinedHostCapability capability) OVERRIDE {
return new HttpPipelinedHostImpl(delegate, origin, factory, capability);
}
};
HttpPipelinedHostPool::HttpPipelinedHostPool(
Delegate* delegate,
- HttpPipelinedHost::Factory* factory)
+ HttpPipelinedHost::Factory* factory,
+ HttpServerProperties* http_server_properties)
: delegate_(delegate),
factory_(factory),
- known_capability_map_(kNumHostsToRemember) {
+ http_server_properties_(http_server_properties) {
if (!factory) {
factory_.reset(new HttpPipelinedHostImplFactory);
}
@@ -42,8 +40,9 @@ HttpPipelinedHostPool::~HttpPipelinedHostPool() {
bool HttpPipelinedHostPool::IsHostEligibleForPipelining(
const HostPortPair& origin) {
- HttpPipelinedHost::Capability capability = GetHostCapability(origin);
- return capability != HttpPipelinedHost::INCAPABLE;
+ HttpPipelinedHostCapability capability =
+ http_server_properties_->GetPipelineCapability(origin);
+ return capability != PIPELINE_INCAPABLE;
}
HttpPipelinedStream* HttpPipelinedHostPool::CreateStreamOnNewPipeline(
@@ -90,8 +89,9 @@ HttpPipelinedHost* HttpPipelinedHostPool::GetPipelinedHost(
return NULL;
}
- HttpPipelinedHost::Capability capability = GetHostCapability(origin);
- if (capability == HttpPipelinedHost::INCAPABLE) {
+ HttpPipelinedHostCapability capability =
+ http_server_properties_->GetPipelineCapability(origin);
+ if (capability == PIPELINE_INCAPABLE) {
return NULL;
}
@@ -115,22 +115,8 @@ void HttpPipelinedHostPool::OnHostHasAdditionalCapacity(
void HttpPipelinedHostPool::OnHostDeterminedCapability(
HttpPipelinedHost* host,
- HttpPipelinedHost::Capability capability) {
- CapabilityMap::iterator known_it = known_capability_map_.Get(host->origin());
- if (known_it == known_capability_map_.end() ||
- known_it->second != HttpPipelinedHost::INCAPABLE) {
- known_capability_map_.Put(host->origin(), capability);
- }
-}
-
-HttpPipelinedHost::Capability HttpPipelinedHostPool::GetHostCapability(
- const HostPortPair& origin) {
- HttpPipelinedHost::Capability capability = HttpPipelinedHost::UNKNOWN;
- CapabilityMap::const_iterator it = known_capability_map_.Get(origin);
- if (it != known_capability_map_.end()) {
- capability = it->second;
- }
- return capability;
+ HttpPipelinedHostCapability capability) {
+ http_server_properties_->SetPipelineCapability(host->origin(), capability);
}
} // namespace net
diff --git a/net/http/http_pipelined_host_pool.h b/net/http/http_pipelined_host_pool.h
index 3be0cb5..67a0b013 100644
--- a/net/http/http_pipelined_host_pool.h
+++ b/net/http/http_pipelined_host_pool.h
@@ -10,14 +10,15 @@
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
-#include "base/memory/mru_cache.h"
#include "base/memory/scoped_ptr.h"
#include "net/http/http_pipelined_host.h"
+#include "net/http/http_pipelined_host_capability.h"
namespace net {
class HostPortPair;
class HttpPipelinedStream;
+class HttpServerProperties;
// Manages all of the pipelining state for specific host with active pipelined
// HTTP requests. Manages connection jobs, constructs pipelined streams, and
@@ -34,7 +35,8 @@ class NET_EXPORT_PRIVATE HttpPipelinedHostPool
};
HttpPipelinedHostPool(Delegate* delegate,
- HttpPipelinedHost::Factory* factory);
+ HttpPipelinedHost::Factory* factory,
+ HttpServerProperties* http_server_properties_);
virtual ~HttpPipelinedHostPool();
// Returns true if pipelining might work for |origin|. Generally, this returns
@@ -67,22 +69,18 @@ class NET_EXPORT_PRIVATE HttpPipelinedHostPool
virtual void OnHostDeterminedCapability(
HttpPipelinedHost* host,
- HttpPipelinedHost::Capability capability) OVERRIDE;
+ HttpPipelinedHostCapability capability) OVERRIDE;
private:
- typedef base::MRUCache<HostPortPair,
- HttpPipelinedHost::Capability> CapabilityMap;
typedef std::map<const HostPortPair, HttpPipelinedHost*> HostMap;
HttpPipelinedHost* GetPipelinedHost(const HostPortPair& origin,
bool create_if_not_found);
- HttpPipelinedHost::Capability GetHostCapability(const HostPortPair& origin);
-
Delegate* delegate_;
scoped_ptr<HttpPipelinedHost::Factory> factory_;
HostMap host_map_;
- CapabilityMap known_capability_map_;
+ HttpServerProperties* http_server_properties_;
DISALLOW_COPY_AND_ASSIGN(HttpPipelinedHostPool);
};
diff --git a/net/http/http_pipelined_host_pool_unittest.cc b/net/http/http_pipelined_host_pool_unittest.cc
index 928e4e9..457f101 100644
--- a/net/http/http_pipelined_host_pool_unittest.cc
+++ b/net/http/http_pipelined_host_pool_unittest.cc
@@ -7,6 +7,8 @@
#include "base/memory/scoped_ptr.h"
#include "net/base/ssl_config_service.h"
#include "net/http/http_pipelined_host.h"
+#include "net/http/http_pipelined_host_capability.h"
+#include "net/http/http_server_properties_impl.h"
#include "net/proxy/proxy_info.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -36,7 +38,7 @@ class MockHostFactory : public HttpPipelinedHost::Factory {
MOCK_METHOD4(CreateNewHost, HttpPipelinedHost*(
HttpPipelinedHost::Delegate* delegate, const HostPortPair& origin,
HttpPipelinedConnection::Factory* factory,
- HttpPipelinedHost::Capability capability));
+ HttpPipelinedHostCapability capability));
};
class MockHost : public HttpPipelinedHost {
@@ -66,7 +68,9 @@ class HttpPipelinedHostPoolTest : public testing::Test {
: origin_("host", 123),
factory_(new MockHostFactory), // Owned by pool_.
host_(new MockHost(origin_)), // Owned by pool_.
- pool_(new HttpPipelinedHostPool(&delegate_, factory_)),
+ http_server_properties_(new HttpServerPropertiesImpl),
+ pool_(new HttpPipelinedHostPool(&delegate_, factory_,
+ http_server_properties_.get())),
was_npn_negotiated_(false) {
}
@@ -88,6 +92,7 @@ class HttpPipelinedHostPoolTest : public testing::Test {
MockPoolDelegate delegate_;
MockHostFactory* factory_;
MockHost* host_;
+ scoped_ptr<HttpServerPropertiesImpl> http_server_properties_;
scoped_ptr<HttpPipelinedHostPool> pool_;
const SSLConfig ssl_config_;
@@ -99,7 +104,7 @@ class HttpPipelinedHostPoolTest : public testing::Test {
TEST_F(HttpPipelinedHostPoolTest, DefaultUnknown) {
EXPECT_TRUE(pool_->IsHostEligibleForPipelining(origin_));
EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(origin_), _,
- HttpPipelinedHost::UNKNOWN))
+ PIPELINE_UNKNOWN))
.Times(1)
.WillOnce(Return(host_));
@@ -109,16 +114,16 @@ TEST_F(HttpPipelinedHostPoolTest, DefaultUnknown) {
TEST_F(HttpPipelinedHostPoolTest, RemembersIncapable) {
EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(origin_), _,
- HttpPipelinedHost::UNKNOWN))
+ PIPELINE_UNKNOWN))
.Times(1)
.WillOnce(Return(host_));
CreateDummyStream();
- pool_->OnHostDeterminedCapability(host_, HttpPipelinedHost::INCAPABLE);
+ pool_->OnHostDeterminedCapability(host_, PIPELINE_INCAPABLE);
pool_->OnHostIdle(host_);
EXPECT_FALSE(pool_->IsHostEligibleForPipelining(origin_));
EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(origin_), _,
- HttpPipelinedHost::INCAPABLE))
+ PIPELINE_INCAPABLE))
.Times(0);
EXPECT_EQ(NULL,
pool_->CreateStreamOnNewPipeline(origin_, kDummyConnection,
@@ -128,18 +133,18 @@ TEST_F(HttpPipelinedHostPoolTest, RemembersIncapable) {
TEST_F(HttpPipelinedHostPoolTest, RemembersCapable) {
EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(origin_), _,
- HttpPipelinedHost::UNKNOWN))
+ PIPELINE_UNKNOWN))
.Times(1)
.WillOnce(Return(host_));
CreateDummyStream();
- pool_->OnHostDeterminedCapability(host_, HttpPipelinedHost::CAPABLE);
+ pool_->OnHostDeterminedCapability(host_, PIPELINE_CAPABLE);
pool_->OnHostIdle(host_);
EXPECT_TRUE(pool_->IsHostEligibleForPipelining(origin_));
host_ = new MockHost(origin_);
EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(origin_), _,
- HttpPipelinedHost::CAPABLE))
+ PIPELINE_CAPABLE))
.Times(1)
.WillOnce(Return(host_));
CreateDummyStream();
@@ -148,21 +153,21 @@ TEST_F(HttpPipelinedHostPoolTest, RemembersCapable) {
TEST_F(HttpPipelinedHostPoolTest, IncapableIsSticky) {
EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(origin_), _,
- HttpPipelinedHost::UNKNOWN))
+ PIPELINE_UNKNOWN))
.Times(1)
.WillOnce(Return(host_));
CreateDummyStream();
- pool_->OnHostDeterminedCapability(host_, HttpPipelinedHost::CAPABLE);
- pool_->OnHostDeterminedCapability(host_, HttpPipelinedHost::INCAPABLE);
- pool_->OnHostDeterminedCapability(host_, HttpPipelinedHost::CAPABLE);
+ pool_->OnHostDeterminedCapability(host_, PIPELINE_CAPABLE);
+ pool_->OnHostDeterminedCapability(host_, PIPELINE_INCAPABLE);
+ pool_->OnHostDeterminedCapability(host_, PIPELINE_CAPABLE);
pool_->OnHostIdle(host_);
EXPECT_FALSE(pool_->IsHostEligibleForPipelining(origin_));
}
TEST_F(HttpPipelinedHostPoolTest, RemainsUnknownWithoutFeedback) {
EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(origin_), _,
- HttpPipelinedHost::UNKNOWN))
+ PIPELINE_UNKNOWN))
.Times(1)
.WillOnce(Return(host_));
@@ -172,7 +177,7 @@ TEST_F(HttpPipelinedHostPoolTest, RemainsUnknownWithoutFeedback) {
host_ = new MockHost(origin_);
EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(origin_), _,
- HttpPipelinedHost::UNKNOWN))
+ PIPELINE_UNKNOWN))
.Times(1)
.WillOnce(Return(host_));
@@ -180,6 +185,14 @@ TEST_F(HttpPipelinedHostPoolTest, RemainsUnknownWithoutFeedback) {
pool_->OnHostIdle(host_);
}
+TEST_F(HttpPipelinedHostPoolTest, PopulatesServerProperties) {
+ EXPECT_EQ(PIPELINE_UNKNOWN,
+ http_server_properties_->GetPipelineCapability(host_->origin()));
+ pool_->OnHostDeterminedCapability(host_, PIPELINE_CAPABLE);
+ EXPECT_EQ(PIPELINE_CAPABLE,
+ http_server_properties_->GetPipelineCapability(host_->origin()));
+}
+
} // anonymous namespace
} // namespace net
diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h
index 51171c2..cd4ae4b 100644
--- a/net/http/http_server_properties.h
+++ b/net/http/http_server_properties.h
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_export.h"
+#include "net/http/http_pipelined_host_capability.h"
#include "net/spdy/spdy_framer.h" // TODO(willchan): Reconsider this.
namespace net {
@@ -35,6 +36,8 @@ struct NET_EXPORT PortAlternateProtocolPair {
typedef std::map<HostPortPair, PortAlternateProtocolPair> AlternateProtocolMap;
typedef std::map<HostPortPair, spdy::SpdySettings> SpdySettingsMap;
+typedef std::map<HostPortPair,
+ HttpPipelinedHostCapability> PipelineCapabilityMap;
extern const char kAlternateProtocolHeader[];
extern const char* const kAlternateProtocolStrings[NUM_ALTERNATE_PROTOCOLS];
@@ -95,6 +98,17 @@ class NET_EXPORT HttpServerProperties {
// Returns all persistent SpdySettings.
virtual const SpdySettingsMap& spdy_settings_map() const = 0;
+ virtual HttpPipelinedHostCapability GetPipelineCapability(
+ const HostPortPair& origin) = 0;
+
+ virtual void SetPipelineCapability(
+ const HostPortPair& origin,
+ HttpPipelinedHostCapability capability) = 0;
+
+ virtual void ClearPipelineCapabilities() = 0;
+
+ virtual PipelineCapabilityMap GetPipelineCapabilityMap() const = 0;
+
private:
DISALLOW_COPY_AND_ASSIGN(HttpServerProperties);
};
diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc
index d4e1303..b8a7ed1 100644
--- a/net/http/http_server_properties_impl.cc
+++ b/net/http/http_server_properties_impl.cc
@@ -8,10 +8,18 @@
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "base/stringprintf.h"
+#include "net/http/http_pipelined_host_capability.h"
namespace net {
-HttpServerPropertiesImpl::HttpServerPropertiesImpl() {
+// TODO(simonjam): Run experiments with different values of this to see what
+// value is good at avoiding evictions without eating too much memory. Until
+// then, this is just a bad guess.
+static const int kDefaultNumHostsToRemember = 200;
+
+HttpServerPropertiesImpl::HttpServerPropertiesImpl()
+ : pipeline_capability_map_(
+ new CachedPipelineCapabilityMap(kDefaultNumHostsToRemember)) {
}
HttpServerPropertiesImpl::~HttpServerPropertiesImpl() {
@@ -48,6 +56,21 @@ void HttpServerPropertiesImpl::InitializeSpdySettingsServers(
spdy_settings_map_.swap(*spdy_settings_map);
}
+void HttpServerPropertiesImpl::InitializePipelineCapabilities(
+ const PipelineCapabilityMap* pipeline_capability_map) {
+ PipelineCapabilityMap::const_iterator it;
+ pipeline_capability_map_->Clear();
+ for (it = pipeline_capability_map->begin();
+ it != pipeline_capability_map->end(); ++it) {
+ pipeline_capability_map_->Put(it->first, it->second);
+ }
+}
+
+void HttpServerPropertiesImpl::SetNumPipelinedHostsToRemember(int max_size) {
+ DCHECK(pipeline_capability_map_->empty());
+ pipeline_capability_map_.reset(new CachedPipelineCapabilityMap(max_size));
+}
+
void HttpServerPropertiesImpl::GetSpdyServerList(
base::ListValue* spdy_server_list) const {
DCHECK(CalledOnValidThread());
@@ -94,6 +117,7 @@ void HttpServerPropertiesImpl::Clear() {
spdy_servers_table_.clear();
alternate_protocol_map_.clear();
spdy_settings_map_.clear();
+ pipeline_capability_map_->Clear();
}
bool HttpServerPropertiesImpl::SupportsSpdy(
@@ -239,4 +263,41 @@ HttpServerPropertiesImpl::spdy_settings_map() const {
return spdy_settings_map_;
}
+HttpPipelinedHostCapability HttpServerPropertiesImpl::GetPipelineCapability(
+ const HostPortPair& origin) {
+ HttpPipelinedHostCapability capability = PIPELINE_UNKNOWN;
+ CachedPipelineCapabilityMap::const_iterator it =
+ pipeline_capability_map_->Get(origin);
+ if (it != pipeline_capability_map_->end()) {
+ capability = it->second;
+ }
+ return capability;
+}
+
+void HttpServerPropertiesImpl::SetPipelineCapability(
+ const HostPortPair& origin,
+ HttpPipelinedHostCapability capability) {
+ CachedPipelineCapabilityMap::iterator it =
+ pipeline_capability_map_->Peek(origin);
+ if (it == pipeline_capability_map_->end() ||
+ it->second != PIPELINE_INCAPABLE) {
+ pipeline_capability_map_->Put(origin, capability);
+ }
+}
+
+void HttpServerPropertiesImpl::ClearPipelineCapabilities() {
+ pipeline_capability_map_->Clear();
+}
+
+PipelineCapabilityMap
+HttpServerPropertiesImpl::GetPipelineCapabilityMap() const {
+ PipelineCapabilityMap result;
+ CachedPipelineCapabilityMap::const_iterator it;
+ for (it = pipeline_capability_map_->begin();
+ it != pipeline_capability_map_->end(); ++it) {
+ result[it->first] = it->second;
+ }
+ return result;
+}
+
} // namespace net
diff --git a/net/http/http_server_properties_impl.h b/net/http/http_server_properties_impl.h
index f697848..487e0fd 100644
--- a/net/http/http_server_properties_impl.h
+++ b/net/http/http_server_properties_impl.h
@@ -12,10 +12,12 @@
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/hash_tables.h"
+#include "base/memory/mru_cache.h"
#include "base/threading/non_thread_safe.h"
#include "base/values.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_export.h"
+#include "net/http/http_pipelined_host_capability.h"
#include "net/http/http_server_properties.h"
namespace base {
@@ -42,6 +44,11 @@ class NET_EXPORT HttpServerPropertiesImpl
void InitializeSpdySettingsServers(SpdySettingsMap* spdy_settings_map);
+ // Initializes |pipeline_capability_map_| with the servers (host/port) from
+ // |pipeline_capability_map| that either support HTTP pipelining or not.
+ void InitializePipelineCapabilities(
+ const PipelineCapabilityMap* pipeline_capability_map);
+
// Get the list of servers (host/port) that support SPDY.
void GetSpdyServerList(base::ListValue* spdy_server_list) const;
@@ -56,6 +63,12 @@ class NET_EXPORT HttpServerPropertiesImpl
static void ForceAlternateProtocol(const PortAlternateProtocolPair& pair);
static void DisableForcedAlternateProtocol();
+ // Changes the number of host/port pairs we remember pipelining capability
+ // for. A larger number means we're more likely to be able to pipeline
+ // immediately if a host is known good, but uses more memory. This function
+ // can only be called if |pipeline_capability_map_| is empty.
+ void SetNumPipelinedHostsToRemember(int max_size);
+
// -----------------------------
// HttpServerProperties methods:
// -----------------------------
@@ -106,7 +119,20 @@ class NET_EXPORT HttpServerPropertiesImpl
// Returns all persistent SpdySettings.
virtual const SpdySettingsMap& spdy_settings_map() const OVERRIDE;
+ virtual HttpPipelinedHostCapability GetPipelineCapability(
+ const HostPortPair& origin) OVERRIDE;
+
+ virtual void SetPipelineCapability(
+ const HostPortPair& origin,
+ HttpPipelinedHostCapability capability) OVERRIDE;
+
+ virtual void ClearPipelineCapabilities() OVERRIDE;
+
+ virtual PipelineCapabilityMap GetPipelineCapabilityMap() const OVERRIDE;
+
private:
+ typedef base::MRUCache<
+ HostPortPair, HttpPipelinedHostCapability> CachedPipelineCapabilityMap;
// |spdy_servers_table_| has flattened representation of servers (host/port
// pair) that either support or not support SPDY protocol.
typedef base::hash_map<std::string, bool> SpdyServerHostPortTable;
@@ -114,6 +140,7 @@ class NET_EXPORT HttpServerPropertiesImpl
AlternateProtocolMap alternate_protocol_map_;
SpdySettingsMap spdy_settings_map_;
+ scoped_ptr<CachedPipelineCapabilityMap> pipeline_capability_map_;
DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesImpl);
};
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc
index dd7776f..735532d 100644
--- a/net/http/http_stream_factory_impl.cc
+++ b/net/http/http_stream_factory_impl.cc
@@ -37,7 +37,8 @@ GURL UpgradeUrlToHttps(const GURL& original_url, int port) {
HttpStreamFactoryImpl::HttpStreamFactoryImpl(HttpNetworkSession* session)
: session_(session),
- http_pipelined_host_pool_(this, NULL) {}
+ http_pipelined_host_pool_(this, NULL,
+ session_->http_server_properties()) {}
HttpStreamFactoryImpl::~HttpStreamFactoryImpl() {
DCHECK(request_map_.empty());
diff --git a/net/net.gyp b/net/net.gyp
index ee63fd2..446c628 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -436,6 +436,7 @@
'http/http_pipelined_connection_impl.cc',
'http/http_pipelined_connection_impl.h',
'http/http_pipelined_host.h',
+ 'http/http_pipelined_host_capability.h',
'http/http_pipelined_host_impl.cc',
'http/http_pipelined_host_impl.h',
'http/http_pipelined_host_pool.cc',