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

Side by Side Diff: net/base/tcp_client_socket_pool.cc

Issue 128001: Revert "Make TCPClientSocketPool own the ConnectingSockets." (Closed)
Patch Set: Created 11 years, 6 months 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
« no previous file with comments | « net/base/tcp_client_socket_pool.h ('k') | net/url_request/url_request_unittest.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/tcp_client_socket_pool.h" 5 #include "net/base/tcp_client_socket_pool.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/field_trial.h" 8 #include "base/field_trial.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/time.h" 10 #include "base/time.h"
(...skipping 27 matching lines...) Expand all
38 const ClientSocketHandle* handle, 38 const ClientSocketHandle* handle,
39 ClientSocketFactory* client_socket_factory, 39 ClientSocketFactory* client_socket_factory,
40 TCPClientSocketPool* pool) 40 TCPClientSocketPool* pool)
41 : group_name_(group_name), 41 : group_name_(group_name),
42 handle_(handle), 42 handle_(handle),
43 client_socket_factory_(client_socket_factory), 43 client_socket_factory_(client_socket_factory),
44 ALLOW_THIS_IN_INITIALIZER_LIST( 44 ALLOW_THIS_IN_INITIALIZER_LIST(
45 callback_(this, 45 callback_(this,
46 &TCPClientSocketPool::ConnectingSocket::OnIOComplete)), 46 &TCPClientSocketPool::ConnectingSocket::OnIOComplete)),
47 pool_(pool), 47 pool_(pool),
48 resolver_(pool->GetHostResolver()) {} 48 resolver_(pool->GetHostResolver()),
49 canceled_(false) {
50 CHECK(!ContainsKey(pool_->connecting_socket_map_, handle));
51 pool_->connecting_socket_map_[handle] = this;
52 }
49 53
50 TCPClientSocketPool::ConnectingSocket::~ConnectingSocket() { 54 TCPClientSocketPool::ConnectingSocket::~ConnectingSocket() {
51 // We don't worry about cancelling the host resolution and TCP connect, since 55 if (!canceled_)
52 // ~SingleRequestHostResolver and ~ClientSocket will take care of it. 56 pool_->connecting_socket_map_.erase(handle_);
53 } 57 }
54 58
55 int TCPClientSocketPool::ConnectingSocket::Connect( 59 int TCPClientSocketPool::ConnectingSocket::Connect(
56 const HostResolver::RequestInfo& resolve_info) { 60 const HostResolver::RequestInfo& resolve_info) {
61 CHECK(!canceled_);
57 int rv = resolver_.Resolve(resolve_info, &addresses_, &callback_); 62 int rv = resolver_.Resolve(resolve_info, &addresses_, &callback_);
58 if (rv != ERR_IO_PENDING) 63 if (rv != ERR_IO_PENDING)
59 rv = OnIOCompleteInternal(rv, true /* synchronous */); 64 rv = OnIOCompleteInternal(rv, true /* synchronous */);
60 return rv; 65 return rv;
61 } 66 }
62 67
63 void TCPClientSocketPool::ConnectingSocket::OnIOComplete(int result) { 68 void TCPClientSocketPool::ConnectingSocket::OnIOComplete(int result) {
64 OnIOCompleteInternal(result, false /* asynchronous */); 69 OnIOCompleteInternal(result, false /* asynchronous */);
65 } 70 }
66 71
67 int TCPClientSocketPool::ConnectingSocket::OnIOCompleteInternal( 72 int TCPClientSocketPool::ConnectingSocket::OnIOCompleteInternal(
68 int result, bool synchronous) { 73 int result, bool synchronous) {
69 CHECK(result != ERR_IO_PENDING); 74 CHECK(result != ERR_IO_PENDING);
70 75
76 if (canceled_) {
77 // We got canceled, so bail out.
78 delete this;
79 return result;
80 }
81
71 GroupMap::iterator group_it = pool_->group_map_.find(group_name_); 82 GroupMap::iterator group_it = pool_->group_map_.find(group_name_);
72 CHECK(group_it != pool_->group_map_.end()); 83 if (group_it == pool_->group_map_.end()) {
84 // The request corresponding to this ConnectingSocket has been canceled.
85 // Stop bothering with it.
86 delete this;
87 return result;
88 }
73 89
74 Group& group = group_it->second; 90 Group& group = group_it->second;
75 91
76 RequestMap* request_map = &group.connecting_requests; 92 RequestMap* request_map = &group.connecting_requests;
77 RequestMap::iterator it = request_map->find(handle_); 93 RequestMap::iterator it = request_map->find(handle_);
78 CHECK(it != request_map->end()); 94 if (it == request_map->end()) {
95 // The request corresponding to this ConnectingSocket has been canceled.
96 // Stop bothering with it.
97 delete this;
98 return result;
99 }
79 100
80 if (result == OK && it->second.load_state == LOAD_STATE_RESOLVING_HOST) { 101 if (result == OK && it->second.load_state == LOAD_STATE_RESOLVING_HOST) {
81 it->second.load_state = LOAD_STATE_CONNECTING; 102 it->second.load_state = LOAD_STATE_CONNECTING;
82 socket_.reset(client_socket_factory_->CreateTCPClientSocket(addresses_)); 103 socket_.reset(client_socket_factory_->CreateTCPClientSocket(addresses_));
83 connect_start_time_ = base::Time::Now(); 104 connect_start_time_ = base::Time::Now();
84 result = socket_->Connect(&callback_); 105 result = socket_->Connect(&callback_);
85 if (result == ERR_IO_PENDING) 106 if (result == ERR_IO_PENDING)
86 return result; 107 return result;
87 } 108 }
88 109
89 if (result == OK) { 110 if (result == OK) {
90 CHECK(it->second.load_state == LOAD_STATE_CONNECTING);
91 CHECK(connect_start_time_ != base::Time()); 111 CHECK(connect_start_time_ != base::Time());
92 base::TimeDelta connect_duration = 112 base::TimeDelta connect_duration =
93 base::Time::Now() - connect_start_time_; 113 base::Time::Now() - connect_start_time_;
94 114
95 UMA_HISTOGRAM_CLIPPED_TIMES("Net.TCP_Connection_Latency", 115 UMA_HISTOGRAM_CLIPPED_TIMES("Net.TCP_Connection_Latency",
96 connect_duration, 116 connect_duration,
97 base::TimeDelta::FromMilliseconds(1), 117 base::TimeDelta::FromMilliseconds(1),
98 base::TimeDelta::FromMinutes(10), 118 base::TimeDelta::FromMinutes(10),
99 100); 119 100);
100 } 120 }
(...skipping 13 matching lines...) Expand all
114 // Delete group if no longer needed. 134 // Delete group if no longer needed.
115 if (group.active_socket_count == 0 && group.idle_sockets.empty()) { 135 if (group.active_socket_count == 0 && group.idle_sockets.empty()) {
116 CHECK(group.pending_requests.empty()); 136 CHECK(group.pending_requests.empty());
117 CHECK(group.connecting_requests.empty()); 137 CHECK(group.connecting_requests.empty());
118 pool_->group_map_.erase(group_it); 138 pool_->group_map_.erase(group_it);
119 } 139 }
120 } 140 }
121 141
122 if (!synchronous) 142 if (!synchronous)
123 request.callback->Run(result); 143 request.callback->Run(result);
124 pool_->RemoveConnectingSocket(handle_); // will delete |this|. 144 delete this;
125 return result; 145 return result;
126 } 146 }
127 147
148 void TCPClientSocketPool::ConnectingSocket::Cancel() {
149 CHECK(!canceled_);
150 CHECK(ContainsKey(pool_->connecting_socket_map_, handle_));
151 pool_->connecting_socket_map_.erase(handle_);
152 canceled_ = true;
153 }
154
128 TCPClientSocketPool::TCPClientSocketPool( 155 TCPClientSocketPool::TCPClientSocketPool(
129 int max_sockets_per_group, 156 int max_sockets_per_group,
130 HostResolver* host_resolver, 157 HostResolver* host_resolver,
131 ClientSocketFactory* client_socket_factory) 158 ClientSocketFactory* client_socket_factory)
132 : client_socket_factory_(client_socket_factory), 159 : client_socket_factory_(client_socket_factory),
133 idle_socket_count_(0), 160 idle_socket_count_(0),
134 max_sockets_per_group_(max_sockets_per_group), 161 max_sockets_per_group_(max_sockets_per_group),
135 host_resolver_(host_resolver) { 162 host_resolver_(host_resolver) {
136 } 163 }
137 164
138 TCPClientSocketPool::~TCPClientSocketPool() { 165 TCPClientSocketPool::~TCPClientSocketPool() {
139 // Clean up any idle sockets. Assert that we have no remaining active 166 // Clean up any idle sockets. Assert that we have no remaining active
140 // sockets or pending requests. They should have all been cleaned up prior 167 // sockets or pending requests. They should have all been cleaned up prior
141 // to the manager being destroyed. 168 // to the manager being destroyed.
142 CloseIdleSockets(); 169 CloseIdleSockets();
143 DCHECK(group_map_.empty()); 170 DCHECK(group_map_.empty());
144 DCHECK(connecting_socket_map_.empty());
145 } 171 }
146 172
147 // InsertRequestIntoQueue inserts the request into the queue based on 173 // InsertRequestIntoQueue inserts the request into the queue based on
148 // priority. Highest priorities are closest to the front. Older requests are 174 // priority. Highest priorities are closest to the front. Older requests are
149 // prioritized over requests of equal priority. 175 // prioritized over requests of equal priority.
150 // 176 //
151 // static 177 // static
152 void TCPClientSocketPool::InsertRequestIntoQueue( 178 void TCPClientSocketPool::InsertRequestIntoQueue(
153 const Request& r, RequestQueue* pending_requests) { 179 const Request& r, RequestQueue* pending_requests) {
154 RequestQueue::iterator it = pending_requests->begin(); 180 RequestQueue::iterator it = pending_requests->begin();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 // We found one we can reuse! 212 // We found one we can reuse!
187 handle->set_socket(idle_socket.socket); 213 handle->set_socket(idle_socket.socket);
188 handle->set_is_reused(true); 214 handle->set_is_reused(true);
189 return OK; 215 return OK;
190 } 216 }
191 delete idle_socket.socket; 217 delete idle_socket.socket;
192 } 218 }
193 219
194 // We couldn't find a socket to reuse, so allocate and connect a new one. 220 // We couldn't find a socket to reuse, so allocate and connect a new one.
195 221
222 // First, we need to make sure we aren't already servicing a request for this
223 // handle (which could happen if we requested, canceled, and then requested
224 // with the same handle).
225 if (ContainsKey(connecting_socket_map_, handle))
226 connecting_socket_map_[handle]->Cancel();
227
196 CHECK(callback); 228 CHECK(callback);
197 Request r(handle, callback, priority, resolve_info, 229 Request r(handle, callback, priority, resolve_info,
198 LOAD_STATE_RESOLVING_HOST); 230 LOAD_STATE_RESOLVING_HOST);
199 group_map_[group_name].connecting_requests[handle] = r; 231 group_map_[group_name].connecting_requests[handle] = r;
200 232
201 CHECK(!ContainsKey(connecting_socket_map_, handle)); 233 // connecting_socket will delete itself.
202
203 ConnectingSocket* connecting_socket = 234 ConnectingSocket* connecting_socket =
204 new ConnectingSocket(group_name, handle, client_socket_factory_, this); 235 new ConnectingSocket(group_name, handle, client_socket_factory_, this);
205 connecting_socket_map_[handle] = connecting_socket;
206 int rv = connecting_socket->Connect(resolve_info); 236 int rv = connecting_socket->Connect(resolve_info);
207 return rv; 237 return rv;
208 } 238 }
209 239
210 void TCPClientSocketPool::CancelRequest(const std::string& group_name, 240 void TCPClientSocketPool::CancelRequest(const std::string& group_name,
211 const ClientSocketHandle* handle) { 241 const ClientSocketHandle* handle) {
212 CHECK(ContainsKey(group_map_, group_name)); 242 CHECK(ContainsKey(group_map_, group_name));
213 243
214 Group& group = group_map_[group_name]; 244 Group& group = group_map_[group_name];
215 245
216 // Search pending_requests for matching handle. 246 // Search pending_requests for matching handle.
217 RequestQueue::iterator it = group.pending_requests.begin(); 247 RequestQueue::iterator it = group.pending_requests.begin();
218 for (; it != group.pending_requests.end(); ++it) { 248 for (; it != group.pending_requests.end(); ++it) {
219 if (it->handle == handle) { 249 if (it->handle == handle) {
220 group.pending_requests.erase(it); 250 group.pending_requests.erase(it);
221 return; 251 return;
222 } 252 }
223 } 253 }
224 254
225 // It's invalid to cancel a non-existent request. 255 // It's invalid to cancel a non-existent request.
226 CHECK(ContainsKey(group.connecting_requests, handle)); 256 CHECK(ContainsKey(group.connecting_requests, handle));
227 257
228 RequestMap::iterator map_it = group.connecting_requests.find(handle); 258 RequestMap::iterator map_it = group.connecting_requests.find(handle);
229 if (map_it != group.connecting_requests.end()) { 259 if (map_it != group.connecting_requests.end()) {
230 RemoveConnectingSocket(handle);
231
232 group.connecting_requests.erase(map_it); 260 group.connecting_requests.erase(map_it);
233 group.active_socket_count--; 261 group.active_socket_count--;
234 262
235 // Delete group if no longer needed. 263 // Delete group if no longer needed.
236 if (group.active_socket_count == 0 && group.idle_sockets.empty()) { 264 if (group.active_socket_count == 0 && group.idle_sockets.empty()) {
237 CHECK(group.pending_requests.empty()); 265 CHECK(group.pending_requests.empty());
238 CHECK(group.connecting_requests.empty()); 266 CHECK(group.connecting_requests.empty());
239 group_map_.erase(group_name); 267 group_map_.erase(group_name);
240 } 268 }
241 } 269 }
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 } 412 }
385 413
386 // Delete group if no longer needed. 414 // Delete group if no longer needed.
387 if (group.active_socket_count == 0 && group.idle_sockets.empty()) { 415 if (group.active_socket_count == 0 && group.idle_sockets.empty()) {
388 CHECK(group.pending_requests.empty()); 416 CHECK(group.pending_requests.empty());
389 CHECK(group.connecting_requests.empty()); 417 CHECK(group.connecting_requests.empty());
390 group_map_.erase(i); 418 group_map_.erase(i);
391 } 419 }
392 } 420 }
393 421
394 void TCPClientSocketPool::RemoveConnectingSocket(
395 const ClientSocketHandle* handle) {
396 ConnectingSocketMap::iterator it = connecting_socket_map_.find(handle);
397 CHECK(it != connecting_socket_map_.end());
398 delete it->second;
399 connecting_socket_map_.erase(it);
400 }
401
402 } // namespace net 422 } // namespace net
OLDNEW
« no previous file with comments | « net/base/tcp_client_socket_pool.h ('k') | net/url_request/url_request_unittest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698