Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: net/http/http_pipelined_host_impl.cc

Issue 8586015: Slow start pipelining. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address various feedback Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/http/http_pipelined_host_impl.h"
6
7 #include "base/stl_util.h"
8 #include "net/http/http_pipelined_connection_impl.h"
9 #include "net/http/http_pipelined_stream.h"
10
11 namespace net {
12
13 // TODO(simonjam): Run experiments to see what value minimizes evictions without
14 // costing too much performance. Until then, this is just a bad guess.
15 static const int kNumKnownSuccessesThreshold = 3;
16
17 class HttpPipelinedConnectionImplFactory :
18 public HttpPipelinedConnection::Factory {
19 public:
20 HttpPipelinedConnection* CreateNewPipeline(
21 ClientSocketHandle* connection,
22 HttpPipelinedConnection::Delegate* delegate,
23 const SSLConfig& used_ssl_config,
24 const ProxyInfo& used_proxy_info,
25 const BoundNetLog& net_log,
26 bool was_npn_negotiated) OVERRIDE {
27 return new HttpPipelinedConnectionImpl(connection, delegate,
28 used_ssl_config, used_proxy_info,
29 net_log, was_npn_negotiated);
30 }
31 };
32
33 HttpPipelinedHostImpl::HttpPipelinedHostImpl(
34 HttpPipelinedHost::Delegate* delegate,
35 const HostPortPair& origin,
36 HttpPipelinedConnection::Factory* factory,
37 Capability capability)
38 : delegate_(delegate),
39 origin_(origin),
40 factory_(factory),
41 capability_(capability) {
42 if (!factory) {
43 factory_.reset(new HttpPipelinedConnectionImplFactory());
44 }
45 }
46
47 HttpPipelinedHostImpl::~HttpPipelinedHostImpl() {
48 CHECK(pipelines_.empty());
49 }
50
51 HttpPipelinedStream* HttpPipelinedHostImpl::CreateStreamOnNewPipeline(
52 ClientSocketHandle* connection,
53 const SSLConfig& used_ssl_config,
54 const ProxyInfo& used_proxy_info,
55 const BoundNetLog& net_log,
56 bool was_npn_negotiated) {
57 if (capability_ == INCAPABLE) {
58 return NULL;
59 }
60 HttpPipelinedConnection* pipeline = factory_->CreateNewPipeline(
61 connection, this, used_ssl_config, used_proxy_info, net_log,
62 was_npn_negotiated);
63 PipelineInfo info;
64 pipelines_.insert(std::make_pair(pipeline, info));
65 return pipeline->CreateNewStream();
66 }
67
68 HttpPipelinedStream* HttpPipelinedHostImpl::CreateStreamOnExistingPipeline() {
69 HttpPipelinedConnection* available_pipeline = NULL;
70 for (PipelineInfoMap::iterator it = pipelines_.begin();
71 it != pipelines_.end(); ++it) {
72 if (it->first->usable() &&
73 it->first->active() &&
74 it->first->depth() < GetPipelineCapacity() &&
75 (!available_pipeline ||
76 it->first->depth() < available_pipeline->depth())) {
77 available_pipeline = it->first;
78 }
79 }
80 if (!available_pipeline) {
81 return NULL;
82 }
83 return available_pipeline->CreateNewStream();
84 }
85
86 bool HttpPipelinedHostImpl::IsExistingPipelineAvailable() const {
87 for (PipelineInfoMap::const_iterator it = pipelines_.begin();
88 it != pipelines_.end(); ++it) {
89 if (it->first->usable() &&
90 it->first->active() &&
91 it->first->depth() < GetPipelineCapacity()) {
92 return true;
93 }
94 }
95 return false;
96 }
97
98 const HostPortPair& HttpPipelinedHostImpl::origin() const {
99 return origin_;
100 }
101
102 void HttpPipelinedHostImpl::OnPipelineEmpty(HttpPipelinedConnection* pipeline) {
103 CHECK(ContainsKey(pipelines_, pipeline));
104 pipelines_.erase(pipeline);
105 delete pipeline;
106 if (pipelines_.empty()) {
107 delegate_->OnHostIdle(this);
108 // WARNING: We'll probably be deleted here.
109 }
110 }
111
112 void HttpPipelinedHostImpl::OnPipelineHasCapacity(
113 HttpPipelinedConnection* pipeline) {
114 CHECK(ContainsKey(pipelines_, pipeline));
115 if (pipeline->usable() &&
116 capability_ != INCAPABLE &&
117 pipeline->depth() < GetPipelineCapacity()) {
118 delegate_->OnHostHasAdditionalCapacity(this);
119 }
120 if (!pipeline->depth()) {
121 OnPipelineEmpty(pipeline);
122 // WARNING: We might be deleted here.
123 }
124 }
125
126 void HttpPipelinedHostImpl::OnPipelineFeedback(
127 HttpPipelinedConnection* pipeline,
128 HttpPipelinedConnection::Feedback feedback) {
129 CHECK(ContainsKey(pipelines_, pipeline));
130 switch (feedback) {
131 case HttpPipelinedConnection::OK:
132 ++pipelines_[pipeline].num_successes;
133 if (capability_ == UNKNOWN) {
134 capability_ = PROBABLY_CAPABLE;
135 for (PipelineInfoMap::iterator it = pipelines_.begin();
136 it != pipelines_.end(); ++it) {
137 OnPipelineHasCapacity(it->first);
mmenke 2011/12/01 17:22:48 We may want a unit test for this behavior at some
James Simonsen 2011/12/01 20:36:42 Done.
138 }
139 } else if (capability_ == PROBABLY_CAPABLE &&
140 pipelines_[pipeline].num_successes >=
141 kNumKnownSuccessesThreshold) {
mmenke 2011/12/01 17:22:48 Could you indent this 4 more spaces, to make it a
James Simonsen 2011/12/01 20:36:42 Done.
142 capability_ = CAPABLE;
143 delegate_->OnHostDeterminedCapability(this, CAPABLE);
144 }
145 break;
146
147 case HttpPipelinedConnection::PIPELINE_SOCKET_ERROR:
148 case HttpPipelinedConnection::OLD_HTTP_VERSION:
149 capability_ = INCAPABLE;
150 delegate_->OnHostDeterminedCapability(this, INCAPABLE);
151 break;
152
153 case HttpPipelinedConnection::MUST_CLOSE_CONNECTION:
154 break;
155 }
156 }
157
158 int HttpPipelinedHostImpl::GetPipelineCapacity() const {
159 int capacity = 0;
160 switch (capability_) {
161 case CAPABLE:
162 case PROBABLY_CAPABLE:
163 capacity = max_pipeline_depth();
164 break;
165
166 case INCAPABLE:
167 CHECK(false);
168
169 case UNKNOWN:
170 capacity = 1;
171 break;
172
173 default:
174 CHECK(false) << "Unkown pipeline capability: " << capability_;
175 }
176 return capacity;
177 }
178
179 HttpPipelinedHostImpl::PipelineInfo::PipelineInfo()
180 : num_successes(0) {
181 }
182
183 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698