| 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/socket/tcp_client_socket_pool.h" | 5 #include "net/socket/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 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 return; | 226 return; |
| 227 } | 227 } |
| 228 } | 228 } |
| 229 | 229 |
| 230 // It's invalid to cancel a non-existent request. | 230 // It's invalid to cancel a non-existent request. |
| 231 CHECK(ContainsKey(group.connecting_requests, handle)); | 231 CHECK(ContainsKey(group.connecting_requests, handle)); |
| 232 | 232 |
| 233 RequestMap::iterator map_it = group.connecting_requests.find(handle); | 233 RequestMap::iterator map_it = group.connecting_requests.find(handle); |
| 234 if (map_it != group.connecting_requests.end()) { | 234 if (map_it != group.connecting_requests.end()) { |
| 235 RemoveConnectingSocket(handle); | 235 RemoveConnectingSocket(handle); |
| 236 | |
| 237 group.connecting_requests.erase(map_it); | 236 group.connecting_requests.erase(map_it); |
| 238 group.active_socket_count--; | 237 RemoveActiveSocket(group_name, &group); |
| 239 | |
| 240 if (!group.pending_requests.empty()) { | |
| 241 ProcessPendingRequest(group_name, &group); | |
| 242 return; // |group| may be invalid after this, so return to be safe. | |
| 243 } | |
| 244 | |
| 245 // Delete group if no longer needed. | |
| 246 if (group.active_socket_count == 0 && group.idle_sockets.empty()) { | |
| 247 CHECK(group.pending_requests.empty()); | |
| 248 CHECK(group.connecting_requests.empty()); | |
| 249 group_map_.erase(group_name); | |
| 250 return; // |group| is invalid after this, so return to be safe. | |
| 251 } | |
| 252 } | 238 } |
| 253 | |
| 254 CheckSocketCounts(group); | |
| 255 } | 239 } |
| 256 | 240 |
| 257 void ClientSocketPoolBase::ReleaseSocket(const std::string& group_name, | 241 void ClientSocketPoolBase::ReleaseSocket(const std::string& group_name, |
| 258 ClientSocket* socket) { | 242 ClientSocket* socket) { |
| 259 // Run this asynchronously to allow the caller to finish before we let | 243 // Run this asynchronously to allow the caller to finish before we let |
| 260 // another to begin doing work. This also avoids nasty recursion issues. | 244 // another to begin doing work. This also avoids nasty recursion issues. |
| 261 // NOTE: We cannot refer to the handle argument after this method returns. | 245 // NOTE: We cannot refer to the handle argument after this method returns. |
| 262 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( | 246 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( |
| 263 this, &ClientSocketPoolBase::DoReleaseSocket, group_name, socket)); | 247 this, &ClientSocketPoolBase::DoReleaseSocket, group_name, socket)); |
| 264 } | 248 } |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 void ClientSocketPoolBase::DoReleaseSocket(const std::string& group_name, | 350 void ClientSocketPoolBase::DoReleaseSocket(const std::string& group_name, |
| 367 ClientSocket* socket) { | 351 ClientSocket* socket) { |
| 368 GroupMap::iterator i = group_map_.find(group_name); | 352 GroupMap::iterator i = group_map_.find(group_name); |
| 369 CHECK(i != group_map_.end()); | 353 CHECK(i != group_map_.end()); |
| 370 | 354 |
| 371 Group& group = i->second; | 355 Group& group = i->second; |
| 372 | 356 |
| 373 CHECK(group.active_socket_count > 0); | 357 CHECK(group.active_socket_count > 0); |
| 374 CheckSocketCounts(group); | 358 CheckSocketCounts(group); |
| 375 | 359 |
| 376 group.active_socket_count--; | |
| 377 group.sockets_handed_out_count--; | 360 group.sockets_handed_out_count--; |
| 378 | 361 |
| 379 const bool can_reuse = socket->IsConnectedAndIdle(); | 362 const bool can_reuse = socket->IsConnectedAndIdle(); |
| 380 if (can_reuse) { | 363 if (can_reuse) { |
| 381 IdleSocket idle_socket; | 364 IdleSocket idle_socket; |
| 382 idle_socket.socket = socket; | 365 idle_socket.socket = socket; |
| 383 idle_socket.start_time = base::TimeTicks::Now(); | 366 idle_socket.start_time = base::TimeTicks::Now(); |
| 384 | 367 |
| 385 group.idle_sockets.push_back(idle_socket); | 368 group.idle_sockets.push_back(idle_socket); |
| 386 IncrementIdleCount(); | 369 IncrementIdleCount(); |
| 387 } else { | 370 } else { |
| 388 delete socket; | 371 delete socket; |
| 389 } | 372 } |
| 390 | 373 |
| 391 // Process one pending request. | 374 RemoveActiveSocket(group_name, &group); |
| 392 if (!group.pending_requests.empty()) { | |
| 393 ProcessPendingRequest(group_name, &group); | |
| 394 return; | |
| 395 } | |
| 396 | |
| 397 // Delete group if no longer needed. | |
| 398 if (group.active_socket_count == 0 && group.idle_sockets.empty()) { | |
| 399 CHECK(group.pending_requests.empty()); | |
| 400 CHECK(group.connecting_requests.empty()); | |
| 401 group_map_.erase(i); | |
| 402 } else { | |
| 403 CheckSocketCounts(group); | |
| 404 } | |
| 405 } | 375 } |
| 406 | 376 |
| 407 ClientSocketPoolBase::Request* ClientSocketPoolBase::GetConnectingRequest( | 377 ClientSocketPoolBase::Request* ClientSocketPoolBase::GetConnectingRequest( |
| 408 const std::string& group_name, const ClientSocketHandle* handle) { | 378 const std::string& group_name, const ClientSocketHandle* handle) { |
| 409 GroupMap::iterator group_it = group_map_.find(group_name); | 379 GroupMap::iterator group_it = group_map_.find(group_name); |
| 410 if (group_it == group_map_.end()) | 380 if (group_it == group_map_.end()) |
| 411 return NULL; | 381 return NULL; |
| 412 | 382 |
| 413 Group& group = group_it->second; | 383 Group& group = group_it->second; |
| 414 | 384 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 434 | 404 |
| 435 RequestMap* request_map = &group.connecting_requests; | 405 RequestMap* request_map = &group.connecting_requests; |
| 436 | 406 |
| 437 RequestMap::iterator it = request_map->find(handle); | 407 RequestMap::iterator it = request_map->find(handle); |
| 438 CHECK(it != request_map->end()); | 408 CHECK(it != request_map->end()); |
| 439 Request request = it->second; | 409 Request request = it->second; |
| 440 request_map->erase(it); | 410 request_map->erase(it); |
| 441 DCHECK_EQ(request.handle, handle); | 411 DCHECK_EQ(request.handle, handle); |
| 442 | 412 |
| 443 if (deactivate) { | 413 if (deactivate) { |
| 444 group.active_socket_count--; | 414 RemoveActiveSocket(group_name, &group); |
| 445 | |
| 446 // Delete group if no longer needed. | |
| 447 if (group.active_socket_count == 0 && group.idle_sockets.empty()) { | |
| 448 DCHECK(group.pending_requests.empty()); | |
| 449 DCHECK(group.connecting_requests.empty()); | |
| 450 group_map_.erase(group_name); | |
| 451 } else { | |
| 452 CheckSocketCounts(group); | |
| 453 } | |
| 454 } else { | 415 } else { |
| 455 request.handle->set_socket(socket); | 416 request.handle->set_socket(socket); |
| 456 request.handle->set_is_reused(false); | 417 request.handle->set_is_reused(false); |
| 457 group.sockets_handed_out_count++; | 418 group.sockets_handed_out_count++; |
| 458 | 419 |
| 459 CheckSocketCounts(group); | 420 CheckSocketCounts(group); |
| 460 } | 421 } |
| 461 | 422 |
| 462 RemoveConnectingSocket(request.handle); | 423 RemoveConnectingSocket(request.handle); |
| 463 | 424 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 475 } | 436 } |
| 476 | 437 |
| 477 void ClientSocketPoolBase::RemoveConnectingSocket( | 438 void ClientSocketPoolBase::RemoveConnectingSocket( |
| 478 const ClientSocketHandle* handle) { | 439 const ClientSocketHandle* handle) { |
| 479 ConnectingSocketMap::iterator it = connecting_socket_map_.find(handle); | 440 ConnectingSocketMap::iterator it = connecting_socket_map_.find(handle); |
| 480 CHECK(it != connecting_socket_map_.end()); | 441 CHECK(it != connecting_socket_map_.end()); |
| 481 delete it->second; | 442 delete it->second; |
| 482 connecting_socket_map_.erase(it); | 443 connecting_socket_map_.erase(it); |
| 483 } | 444 } |
| 484 | 445 |
| 446 void ClientSocketPoolBase::RemoveActiveSocket(const std::string& group_name, |
| 447 Group* group) { |
| 448 group->active_socket_count--; |
| 449 |
| 450 if (!group->pending_requests.empty()) { |
| 451 ProcessPendingRequest(group_name, group); |
| 452 // |group| may no longer be valid after this point. Be careful not to |
| 453 // access it again. |
| 454 } else if (group->active_socket_count == 0 && group->idle_sockets.empty()) { |
| 455 // Delete |group| if no longer needed. |group| will no longer be valid. |
| 456 DCHECK(group->connecting_requests.empty()); |
| 457 group_map_.erase(group_name); |
| 458 } else { |
| 459 CheckSocketCounts(*group); |
| 460 } |
| 461 } |
| 462 |
| 485 void ClientSocketPoolBase::ProcessPendingRequest(const std::string& group_name, | 463 void ClientSocketPoolBase::ProcessPendingRequest(const std::string& group_name, |
| 486 Group* group) { | 464 Group* group) { |
| 487 Request r = group->pending_requests.front(); | 465 Request r = group->pending_requests.front(); |
| 488 group->pending_requests.pop_front(); | 466 group->pending_requests.pop_front(); |
| 489 | 467 |
| 490 int rv = RequestSocket( | 468 int rv = RequestSocket( |
| 491 group_name, r.resolve_info, r.priority, r.handle, r.callback); | 469 group_name, r.resolve_info, r.priority, r.handle, r.callback); |
| 492 | 470 |
| 493 // |group| may be invalid after RequestSocket. | 471 // |group| may be invalid after RequestSocket. |
| 494 | 472 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 546 const std::string& group_name) const { | 524 const std::string& group_name) const { |
| 547 return base_->IdleSocketCountInGroup(group_name); | 525 return base_->IdleSocketCountInGroup(group_name); |
| 548 } | 526 } |
| 549 | 527 |
| 550 LoadState TCPClientSocketPool::GetLoadState( | 528 LoadState TCPClientSocketPool::GetLoadState( |
| 551 const std::string& group_name, const ClientSocketHandle* handle) const { | 529 const std::string& group_name, const ClientSocketHandle* handle) const { |
| 552 return base_->GetLoadState(group_name, handle); | 530 return base_->GetLoadState(group_name, handle); |
| 553 } | 531 } |
| 554 | 532 |
| 555 } // namespace net | 533 } // namespace net |
| OLD | NEW |