Index: net/http/http_pipelined_host_pool.cc |
diff --git a/net/http/http_pipelined_host_pool.cc b/net/http/http_pipelined_host_pool.cc |
index bd238d85649458a2e3a4f17ce9f1f28840775843..3152799a97baef79695a064199a4c4b527578b24 100644 |
--- a/net/http/http_pipelined_host_pool.cc |
+++ b/net/http/http_pipelined_host_pool.cc |
@@ -6,19 +6,49 @@ |
#include "base/logging.h" |
#include "base/stl_util.h" |
-#include "net/http/http_pipelined_host.h" |
-#include "net/http/http_stream_factory_impl.h" |
+#include "net/http/http_pipelined_host_impl.h" |
namespace net { |
-HttpPipelinedHostPool::HttpPipelinedHostPool(HttpStreamFactoryImpl* factory) |
- : factory_(factory) { |
+// 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 { |
+ return new HttpPipelinedHostImpl(delegate, origin, factory, capability); |
+ } |
+}; |
+ |
+HttpPipelinedHostPool::HttpPipelinedHostPool( |
+ Delegate* delegate, |
+ HttpPipelinedHost::Factory* factory) |
+ : delegate_(delegate), |
+ factory_(factory), |
+ known_capability_map_(kNumHostsToRemember) { |
+ if (!factory) { |
+ factory_.reset(new HttpPipelinedHostImplFactory); |
+ } |
} |
HttpPipelinedHostPool::~HttpPipelinedHostPool() { |
CHECK(host_map_.empty()); |
} |
+bool HttpPipelinedHostPool::IsHostEligibleForPipelining( |
+ const HostPortPair& origin) { |
+ CapabilityMap::iterator it = known_capability_map_.Get(origin); |
+ if (it != known_capability_map_.end()) { |
+ return it->second != HttpPipelinedHost::INCAPABLE; |
+ } |
+ return true; |
+} |
+ |
HttpPipelinedStream* HttpPipelinedHostPool::CreateStreamOnNewPipeline( |
const HostPortPair& origin, |
ClientSocketHandle* connection, |
@@ -27,6 +57,9 @@ HttpPipelinedStream* HttpPipelinedHostPool::CreateStreamOnNewPipeline( |
const BoundNetLog& net_log, |
bool was_npn_negotiated) { |
HttpPipelinedHost* host = GetPipelinedHost(origin, true); |
+ if (!host) { |
+ return NULL; |
+ } |
return host->CreateStreamOnNewPipeline(connection, used_ssl_config, |
used_proxy_info, net_log, |
was_npn_negotiated); |
@@ -52,14 +85,25 @@ bool HttpPipelinedHostPool::IsExistingPipelineAvailableForOrigin( |
HttpPipelinedHost* HttpPipelinedHostPool::GetPipelinedHost( |
const HostPortPair& origin, bool create_if_not_found) { |
- HostMap::iterator it = host_map_.find(origin); |
- if (it != host_map_.end()) { |
- CHECK(it->second); |
- return it->second; |
+ HostMap::iterator host_it = host_map_.find(origin); |
+ if (host_it != host_map_.end()) { |
+ CHECK(host_it->second); |
+ return host_it->second; |
} else if (!create_if_not_found) { |
return NULL; |
} |
- HttpPipelinedHost* host = new HttpPipelinedHost(this, origin, NULL); |
+ |
+ HttpPipelinedHost::Capability capability = HttpPipelinedHost::UNKNOWN; |
+ CapabilityMap::iterator known_it = known_capability_map_.Get(origin); |
+ if (known_it != known_capability_map_.end()) { |
+ capability = known_it->second; |
+ } |
+ if (capability == HttpPipelinedHost::INCAPABLE) { |
+ return NULL; |
+ } |
+ |
+ HttpPipelinedHost* host = factory_->CreateNewHost( |
+ this, origin, NULL, capability); |
host_map_[origin] = host; |
return host; |
} |
@@ -67,14 +111,23 @@ HttpPipelinedHost* HttpPipelinedHostPool::GetPipelinedHost( |
void HttpPipelinedHostPool::OnHostIdle(HttpPipelinedHost* host) { |
const HostPortPair& origin = host->origin(); |
CHECK(ContainsKey(host_map_, origin)); |
- // TODO(simonjam): We should remember the pipeline state for each host. |
host_map_.erase(origin); |
delete host; |
} |
void HttpPipelinedHostPool::OnHostHasAdditionalCapacity( |
HttpPipelinedHost* host) { |
- factory_->OnHttpPipelinedHostHasAdditionalCapacity(host->origin()); |
+ delegate_->OnHttpPipelinedHostHasAdditionalCapacity(host->origin()); |
+} |
+ |
+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); |
+ } |
} |
} // namespace net |