1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
// 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.
#include "net/http/http_pipelined_host_pool.h"
#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 {
class HttpPipelinedHostImplFactory : public HttpPipelinedHost::Factory {
public:
virtual HttpPipelinedHost* CreateNewHost(
HttpPipelinedHost::Delegate* delegate, const HostPortPair& origin,
HttpPipelinedConnection::Factory* factory,
HttpPipelinedHostCapability capability) OVERRIDE {
return new HttpPipelinedHostImpl(delegate, origin, factory, capability);
}
};
HttpPipelinedHostPool::HttpPipelinedHostPool(
Delegate* delegate,
HttpPipelinedHost::Factory* factory,
HttpServerProperties* http_server_properties)
: delegate_(delegate),
factory_(factory),
http_server_properties_(http_server_properties) {
if (!factory) {
factory_.reset(new HttpPipelinedHostImplFactory);
}
}
HttpPipelinedHostPool::~HttpPipelinedHostPool() {
CHECK(host_map_.empty());
}
bool HttpPipelinedHostPool::IsHostEligibleForPipelining(
const HostPortPair& origin) {
HttpPipelinedHostCapability capability =
http_server_properties_->GetPipelineCapability(origin);
return capability != PIPELINE_INCAPABLE;
}
HttpPipelinedStream* HttpPipelinedHostPool::CreateStreamOnNewPipeline(
const HostPortPair& origin,
ClientSocketHandle* connection,
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
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);
}
HttpPipelinedStream* HttpPipelinedHostPool::CreateStreamOnExistingPipeline(
const HostPortPair& origin) {
HttpPipelinedHost* host = GetPipelinedHost(origin, false);
if (!host) {
return NULL;
}
return host->CreateStreamOnExistingPipeline();
}
bool HttpPipelinedHostPool::IsExistingPipelineAvailableForOrigin(
const HostPortPair& origin) {
HttpPipelinedHost* host = GetPipelinedHost(origin, false);
if (!host) {
return false;
}
return host->IsExistingPipelineAvailable();
}
HttpPipelinedHost* HttpPipelinedHostPool::GetPipelinedHost(
const HostPortPair& origin, bool create_if_not_found) {
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;
}
HttpPipelinedHostCapability capability =
http_server_properties_->GetPipelineCapability(origin);
if (capability == PIPELINE_INCAPABLE) {
return NULL;
}
HttpPipelinedHost* host = factory_->CreateNewHost(
this, origin, NULL, capability);
host_map_[origin] = host;
return host;
}
void HttpPipelinedHostPool::OnHostIdle(HttpPipelinedHost* host) {
const HostPortPair& origin = host->origin();
CHECK(ContainsKey(host_map_, origin));
host_map_.erase(origin);
delete host;
}
void HttpPipelinedHostPool::OnHostHasAdditionalCapacity(
HttpPipelinedHost* host) {
delegate_->OnHttpPipelinedHostHasAdditionalCapacity(host->origin());
}
void HttpPipelinedHostPool::OnHostDeterminedCapability(
HttpPipelinedHost* host,
HttpPipelinedHostCapability capability) {
http_server_properties_->SetPipelineCapability(host->origin(), capability);
}
} // namespace net
|