| 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 |