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