OLD | NEW |
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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 CHECK(!ContainsKey(pool_->connecting_socket_map_, handle)); | 51 CHECK(!ContainsKey(pool_->connecting_socket_map_, handle)); |
52 pool_->connecting_socket_map_[handle] = this; | 52 pool_->connecting_socket_map_[handle] = this; |
53 } | 53 } |
54 | 54 |
55 TCPClientSocketPool::ConnectingSocket::~ConnectingSocket() { | 55 TCPClientSocketPool::ConnectingSocket::~ConnectingSocket() { |
56 if (!canceled_) | 56 if (!canceled_) |
57 pool_->connecting_socket_map_.erase(handle_); | 57 pool_->connecting_socket_map_.erase(handle_); |
58 } | 58 } |
59 | 59 |
60 int TCPClientSocketPool::ConnectingSocket::Connect( | 60 int TCPClientSocketPool::ConnectingSocket::Connect( |
61 const std::string& host, | 61 const HostResolver::RequestInfo& resolve_info) { |
62 int port) { | |
63 CHECK(!canceled_); | 62 CHECK(!canceled_); |
64 DidStartDnsResolution(host, this); | 63 int rv = resolver_.Resolve(resolve_info, &addresses_, &callback_); |
65 int rv = resolver_.Resolve(host, port, &addresses_, &callback_); | |
66 if (rv != ERR_IO_PENDING) | 64 if (rv != ERR_IO_PENDING) |
67 rv = OnIOCompleteInternal(rv, true /* synchronous */); | 65 rv = OnIOCompleteInternal(rv, true /* synchronous */); |
68 return rv; | 66 return rv; |
69 } | 67 } |
70 | 68 |
71 void TCPClientSocketPool::ConnectingSocket::OnIOComplete(int result) { | 69 void TCPClientSocketPool::ConnectingSocket::OnIOComplete(int result) { |
72 OnIOCompleteInternal(result, false /* asynchronous */); | 70 OnIOCompleteInternal(result, false /* asynchronous */); |
73 } | 71 } |
74 | 72 |
75 int TCPClientSocketPool::ConnectingSocket::OnIOCompleteInternal( | 73 int TCPClientSocketPool::ConnectingSocket::OnIOCompleteInternal( |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 // | 177 // |
180 // static | 178 // static |
181 void TCPClientSocketPool::InsertRequestIntoQueue( | 179 void TCPClientSocketPool::InsertRequestIntoQueue( |
182 const Request& r, RequestQueue* pending_requests) { | 180 const Request& r, RequestQueue* pending_requests) { |
183 RequestQueue::iterator it = pending_requests->begin(); | 181 RequestQueue::iterator it = pending_requests->begin(); |
184 while (it != pending_requests->end() && r.priority <= it->priority) | 182 while (it != pending_requests->end() && r.priority <= it->priority) |
185 ++it; | 183 ++it; |
186 pending_requests->insert(it, r); | 184 pending_requests->insert(it, r); |
187 } | 185 } |
188 | 186 |
189 int TCPClientSocketPool::RequestSocket(const std::string& group_name, | 187 int TCPClientSocketPool::RequestSocket( |
190 const std::string& host, | 188 const std::string& group_name, |
191 int port, | 189 const HostResolver::RequestInfo& resolve_info, |
192 int priority, | 190 int priority, |
193 ClientSocketHandle* handle, | 191 ClientSocketHandle* handle, |
194 CompletionCallback* callback) { | 192 CompletionCallback* callback) { |
195 DCHECK(!host.empty()); | 193 DCHECK(!resolve_info.hostname().empty()); |
196 DCHECK_GE(priority, 0); | 194 DCHECK_GE(priority, 0); |
197 Group& group = group_map_[group_name]; | 195 Group& group = group_map_[group_name]; |
198 | 196 |
199 // Can we make another active socket now? | 197 // Can we make another active socket now? |
200 if (group.active_socket_count == max_sockets_per_group_) { | 198 if (group.active_socket_count == max_sockets_per_group_) { |
201 Request r; | |
202 r.handle = handle; | |
203 CHECK(callback); | 199 CHECK(callback); |
204 r.callback = callback; | 200 Request r(handle, callback, priority, resolve_info, LOAD_STATE_IDLE); |
205 r.priority = priority; | |
206 r.host = host; | |
207 r.port = port; | |
208 r.load_state = LOAD_STATE_IDLE; | |
209 InsertRequestIntoQueue(r, &group.pending_requests); | 201 InsertRequestIntoQueue(r, &group.pending_requests); |
210 return ERR_IO_PENDING; | 202 return ERR_IO_PENDING; |
211 } | 203 } |
212 | 204 |
213 // OK, we are going to activate one. | 205 // OK, we are going to activate one. |
214 group.active_socket_count++; | 206 group.active_socket_count++; |
215 | 207 |
216 while (!group.idle_sockets.empty()) { | 208 while (!group.idle_sockets.empty()) { |
217 IdleSocket idle_socket = group.idle_sockets.back(); | 209 IdleSocket idle_socket = group.idle_sockets.back(); |
218 group.idle_sockets.pop_back(); | 210 group.idle_sockets.pop_back(); |
219 DecrementIdleCount(); | 211 DecrementIdleCount(); |
220 if (idle_socket.socket->IsConnectedAndIdle()) { | 212 if (idle_socket.socket->IsConnectedAndIdle()) { |
221 // We found one we can reuse! | 213 // We found one we can reuse! |
222 handle->set_socket(idle_socket.socket); | 214 handle->set_socket(idle_socket.socket); |
223 handle->set_is_reused(true); | 215 handle->set_is_reused(true); |
224 return OK; | 216 return OK; |
225 } | 217 } |
226 delete idle_socket.socket; | 218 delete idle_socket.socket; |
227 } | 219 } |
228 | 220 |
229 // We couldn't find a socket to reuse, so allocate and connect a new one. | 221 // We couldn't find a socket to reuse, so allocate and connect a new one. |
230 | 222 |
231 // First, we need to make sure we aren't already servicing a request for this | 223 // First, we need to make sure we aren't already servicing a request for this |
232 // handle (which could happen if we requested, canceled, and then requested | 224 // handle (which could happen if we requested, canceled, and then requested |
233 // with the same handle). | 225 // with the same handle). |
234 if (ContainsKey(connecting_socket_map_, handle)) | 226 if (ContainsKey(connecting_socket_map_, handle)) |
235 connecting_socket_map_[handle]->Cancel(); | 227 connecting_socket_map_[handle]->Cancel(); |
236 | 228 |
237 Request r; | |
238 r.handle = handle; | |
239 CHECK(callback); | 229 CHECK(callback); |
240 r.callback = callback; | 230 Request r(handle, callback, priority, resolve_info, |
241 r.priority = priority; | 231 LOAD_STATE_RESOLVING_HOST); |
242 r.host = host; | |
243 r.port = port; | |
244 r.load_state = LOAD_STATE_RESOLVING_HOST; | |
245 group_map_[group_name].connecting_requests[handle] = r; | 232 group_map_[group_name].connecting_requests[handle] = r; |
246 | 233 |
247 // connecting_socket will delete itself. | 234 // connecting_socket will delete itself. |
248 ConnectingSocket* connecting_socket = | 235 ConnectingSocket* connecting_socket = |
249 new ConnectingSocket(group_name, handle, client_socket_factory_, this); | 236 new ConnectingSocket(group_name, handle, client_socket_factory_, this); |
250 int rv = connecting_socket->Connect(host, port); | 237 int rv = connecting_socket->Connect(resolve_info); |
251 return rv; | 238 return rv; |
252 } | 239 } |
253 | 240 |
254 void TCPClientSocketPool::CancelRequest(const std::string& group_name, | 241 void TCPClientSocketPool::CancelRequest(const std::string& group_name, |
255 const ClientSocketHandle* handle) { | 242 const ClientSocketHandle* handle) { |
256 CHECK(ContainsKey(group_map_, group_name)); | 243 CHECK(ContainsKey(group_map_, group_name)); |
257 | 244 |
258 Group& group = group_map_[group_name]; | 245 Group& group = group_map_[group_name]; |
259 | 246 |
260 // Search pending_requests for matching handle. | 247 // Search pending_requests for matching handle. |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 } else { | 399 } else { |
413 delete socket; | 400 delete socket; |
414 } | 401 } |
415 | 402 |
416 // Process one pending request. | 403 // Process one pending request. |
417 if (!group.pending_requests.empty()) { | 404 if (!group.pending_requests.empty()) { |
418 Request r = group.pending_requests.front(); | 405 Request r = group.pending_requests.front(); |
419 group.pending_requests.pop_front(); | 406 group.pending_requests.pop_front(); |
420 | 407 |
421 int rv = RequestSocket( | 408 int rv = RequestSocket( |
422 group_name, r.host, r.port, r.priority, r.handle, r.callback); | 409 group_name, r.resolve_info, r.priority, r.handle, r.callback); |
423 if (rv != ERR_IO_PENDING) | 410 if (rv != ERR_IO_PENDING) |
424 r.callback->Run(rv); | 411 r.callback->Run(rv); |
425 return; | 412 return; |
426 } | 413 } |
427 | 414 |
428 // Delete group if no longer needed. | 415 // Delete group if no longer needed. |
429 if (group.active_socket_count == 0 && group.idle_sockets.empty()) { | 416 if (group.active_socket_count == 0 && group.idle_sockets.empty()) { |
430 CHECK(group.pending_requests.empty()); | 417 CHECK(group.pending_requests.empty()); |
431 CHECK(group.connecting_requests.empty()); | 418 CHECK(group.connecting_requests.empty()); |
432 group_map_.erase(i); | 419 group_map_.erase(i); |
433 } | 420 } |
434 } | 421 } |
435 | 422 |
436 } // namespace net | 423 } // namespace net |
OLD | NEW |