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

Side by Side Diff: net/socket/client_socket_pool_base.cc

Issue 2647003: Do not attempt to reuse active sockets after a socket pool flush (usually a network change). (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Address eroman comments. Created 10 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/socket/client_socket_pool_base.h ('k') | net/socket/client_socket_pool_base_unittest.cc » ('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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/client_socket_pool_base.h" 5 #include "net/socket/client_socket_pool_base.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/format_macros.h" 8 #include "base/format_macros.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/stats_counters.h" 10 #include "base/stats_counters.h"
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 handed_out_socket_count_(0), 135 handed_out_socket_count_(0),
136 num_releasing_sockets_(0), 136 num_releasing_sockets_(0),
137 max_sockets_(max_sockets), 137 max_sockets_(max_sockets),
138 max_sockets_per_group_(max_sockets_per_group), 138 max_sockets_per_group_(max_sockets_per_group),
139 unused_idle_socket_timeout_(unused_idle_socket_timeout), 139 unused_idle_socket_timeout_(unused_idle_socket_timeout),
140 used_idle_socket_timeout_(used_idle_socket_timeout), 140 used_idle_socket_timeout_(used_idle_socket_timeout),
141 may_have_stalled_group_(false), 141 may_have_stalled_group_(false),
142 connect_job_factory_(connect_job_factory), 142 connect_job_factory_(connect_job_factory),
143 network_change_notifier_(network_change_notifier), 143 network_change_notifier_(network_change_notifier),
144 backup_jobs_enabled_(false), 144 backup_jobs_enabled_(false),
145 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { 145 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
146 pool_generation_number_(0) {
146 DCHECK_LE(0, max_sockets_per_group); 147 DCHECK_LE(0, max_sockets_per_group);
147 DCHECK_LE(max_sockets_per_group, max_sockets); 148 DCHECK_LE(max_sockets_per_group, max_sockets);
148 149
149 if (network_change_notifier_) 150 if (network_change_notifier_)
150 network_change_notifier_->AddObserver(this); 151 network_change_notifier_->AddObserver(this);
151 } 152 }
152 153
153 ClientSocketPoolBaseHelper::~ClientSocketPoolBaseHelper() { 154 ClientSocketPoolBaseHelper::~ClientSocketPoolBaseHelper() {
154 CancelAllConnectJobs(); 155 CancelAllConnectJobs();
155 156
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 // TODO(willchan): Cancel the job in the earliest LoadState. 364 // TODO(willchan): Cancel the job in the earliest LoadState.
364 RemoveConnectJob(*group.jobs.begin(), &group); 365 RemoveConnectJob(*group.jobs.begin(), &group);
365 OnAvailableSocketSlot(group_name, &group); 366 OnAvailableSocketSlot(group_name, &group);
366 } 367 }
367 return; 368 return;
368 } 369 }
369 } 370 }
370 } 371 }
371 372
372 void ClientSocketPoolBaseHelper::ReleaseSocket(const std::string& group_name, 373 void ClientSocketPoolBaseHelper::ReleaseSocket(const std::string& group_name,
373 ClientSocket* socket) { 374 ClientSocket* socket,
375 int id) {
374 Group& group = group_map_[group_name]; 376 Group& group = group_map_[group_name];
375 group.num_releasing_sockets++; 377 group.num_releasing_sockets++;
376 num_releasing_sockets_++; 378 num_releasing_sockets_++;
377 DCHECK_LE(group.num_releasing_sockets, group.active_socket_count); 379 DCHECK_LE(group.num_releasing_sockets, group.active_socket_count);
378 // Run this asynchronously to allow the caller to finish before we let 380 // Run this asynchronously to allow the caller to finish before we let
379 // another to begin doing work. This also avoids nasty recursion issues. 381 // another to begin doing work. This also avoids nasty recursion issues.
380 // NOTE: We cannot refer to the handle argument after this method returns. 382 // NOTE: We cannot refer to the handle argument after this method returns.
381 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 383 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
382 this, &ClientSocketPoolBaseHelper::DoReleaseSocket, group_name, socket)); 384 this, &ClientSocketPoolBaseHelper::DoReleaseSocket, group_name, socket, id ));
383 } 385 }
384 386
385 void ClientSocketPoolBaseHelper::CloseIdleSockets() { 387 void ClientSocketPoolBaseHelper::CloseIdleSockets() {
386 CleanupIdleSockets(true); 388 CleanupIdleSockets(true);
387 } 389 }
388 390
389 int ClientSocketPoolBaseHelper::IdleSocketCountInGroup( 391 int ClientSocketPoolBaseHelper::IdleSocketCountInGroup(
390 const std::string& group_name) const { 392 const std::string& group_name) const {
391 GroupMap::const_iterator i = group_map_.find(group_name); 393 GroupMap::const_iterator i = group_map_.find(group_name);
392 CHECK(i != group_map_.end()); 394 CHECK(i != group_map_.end());
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 timer_.Start(TimeDelta::FromSeconds(kCleanupInterval), this, 478 timer_.Start(TimeDelta::FromSeconds(kCleanupInterval), this,
477 &ClientSocketPoolBaseHelper::OnCleanupTimerFired); 479 &ClientSocketPoolBaseHelper::OnCleanupTimerFired);
478 } 480 }
479 481
480 void ClientSocketPoolBaseHelper::DecrementIdleCount() { 482 void ClientSocketPoolBaseHelper::DecrementIdleCount() {
481 if (--idle_socket_count_ == 0) 483 if (--idle_socket_count_ == 0)
482 timer_.Stop(); 484 timer_.Stop();
483 } 485 }
484 486
485 void ClientSocketPoolBaseHelper::DoReleaseSocket(const std::string& group_name, 487 void ClientSocketPoolBaseHelper::DoReleaseSocket(const std::string& group_name,
486 ClientSocket* socket) { 488 ClientSocket* socket,
489 int id) {
487 // Running callbacks can cause the last outside reference to be released. 490 // Running callbacks can cause the last outside reference to be released.
488 // Hold onto a reference. 491 // Hold onto a reference.
489 scoped_refptr<ClientSocketPoolBaseHelper> ref_holder(this); 492 scoped_refptr<ClientSocketPoolBaseHelper> ref_holder(this);
490 493
491 GroupMap::iterator i = group_map_.find(group_name); 494 GroupMap::iterator i = group_map_.find(group_name);
492 CHECK(i != group_map_.end()); 495 CHECK(i != group_map_.end());
493 496
494 Group& group = i->second; 497 Group& group = i->second;
495 498
496 group.num_releasing_sockets--; 499 group.num_releasing_sockets--;
497 DCHECK_GE(group.num_releasing_sockets, 0); 500 DCHECK_GE(group.num_releasing_sockets, 0);
498 501
499 CHECK_GT(handed_out_socket_count_, 0); 502 CHECK_GT(handed_out_socket_count_, 0);
500 handed_out_socket_count_--; 503 handed_out_socket_count_--;
501 504
502 CHECK_GT(group.active_socket_count, 0); 505 CHECK_GT(group.active_socket_count, 0);
503 group.active_socket_count--; 506 group.active_socket_count--;
504 507
505 CHECK_GT(num_releasing_sockets_, 0); 508 CHECK_GT(num_releasing_sockets_, 0);
506 num_releasing_sockets_--; 509 num_releasing_sockets_--;
507 510
508 const bool can_reuse = socket->IsConnectedAndIdle(); 511 const bool can_reuse = socket->IsConnectedAndIdle() &&
512 id == pool_generation_number_;
509 if (can_reuse) { 513 if (can_reuse) {
510 AddIdleSocket(socket, true /* used socket */, &group); 514 AddIdleSocket(socket, true /* used socket */, &group);
511 } else { 515 } else {
512 delete socket; 516 delete socket;
513 } 517 }
514 518
515 // If there are no more releasing sockets, then we might have to process 519 // If there are no more releasing sockets, then we might have to process
516 // multiple available socket slots, since we stalled their processing until 520 // multiple available socket slots, since we stalled their processing until
517 // all sockets have been released. Note that ProcessPendingRequest() will 521 // all sockets have been released. Note that ProcessPendingRequest() will
518 // invoke user callbacks, so |num_releasing_sockets_| may change. 522 // invoke user callbacks, so |num_releasing_sockets_| may change.
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 group.pending_requests.begin(), &group.pending_requests)); 626 group.pending_requests.begin(), &group.pending_requests));
623 LogBoundConnectJobToRequest(job_log.source(), r.get()); 627 LogBoundConnectJobToRequest(job_log.source(), r.get());
624 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, 628 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL,
625 new NetLogIntegerParameter("net_error", result)); 629 new NetLogIntegerParameter("net_error", result));
626 r->callback()->Run(result); 630 r->callback()->Run(result);
627 } 631 }
628 MaybeOnAvailableSocketSlot(group_name); 632 MaybeOnAvailableSocketSlot(group_name);
629 } 633 }
630 } 634 }
631 635
632 void ClientSocketPoolBaseHelper::OnIPAddressChanged() { 636 void ClientSocketPoolBaseHelper::Flush() {
637 pool_generation_number_++;
633 CancelAllConnectJobs(); 638 CancelAllConnectJobs();
634 CloseIdleSockets(); 639 CloseIdleSockets();
635 } 640 }
636 641
637 void ClientSocketPoolBaseHelper::RemoveConnectJob(const ConnectJob *job, 642 void ClientSocketPoolBaseHelper::RemoveConnectJob(const ConnectJob *job,
638 Group* group) { 643 Group* group) {
639 CHECK_GT(connecting_socket_count_, 0); 644 CHECK_GT(connecting_socket_count_, 0);
640 connecting_socket_count_--; 645 connecting_socket_count_--;
641 646
642 DCHECK(job); 647 DCHECK(job);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 ClientSocket* socket, 710 ClientSocket* socket,
706 bool reused, 711 bool reused,
707 ClientSocketHandle* handle, 712 ClientSocketHandle* handle,
708 base::TimeDelta idle_time, 713 base::TimeDelta idle_time,
709 Group* group, 714 Group* group,
710 const BoundNetLog& net_log) { 715 const BoundNetLog& net_log) {
711 DCHECK(socket); 716 DCHECK(socket);
712 handle->set_socket(socket); 717 handle->set_socket(socket);
713 handle->set_is_reused(reused); 718 handle->set_is_reused(reused);
714 handle->set_idle_time(idle_time); 719 handle->set_idle_time(idle_time);
720 handle->set_pool_id(pool_generation_number_);
715 721
716 if (reused) { 722 if (reused) {
717 net_log.AddEvent( 723 net_log.AddEvent(
718 NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET, 724 NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET,
719 new NetLogIntegerParameter( 725 new NetLogIntegerParameter(
720 "idle_ms", static_cast<int>(idle_time.InMilliseconds()))); 726 "idle_ms", static_cast<int>(idle_time.InMilliseconds())));
721 } 727 }
722 728
723 net_log.AddEvent(NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET, 729 net_log.AddEvent(NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
724 new NetLogSourceParameter( 730 new NetLogSourceParameter(
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 DCHECK_LE(total, max_sockets_); 772 DCHECK_LE(total, max_sockets_);
767 if (total < max_sockets_) 773 if (total < max_sockets_)
768 return false; 774 return false;
769 LOG(WARNING) << "ReachedMaxSocketsLimit: " << total << "/" << max_sockets_; 775 LOG(WARNING) << "ReachedMaxSocketsLimit: " << total << "/" << max_sockets_;
770 return true; 776 return true;
771 } 777 }
772 778
773 } // namespace internal 779 } // namespace internal
774 780
775 } // namespace net 781 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/client_socket_pool_base.h ('k') | net/socket/client_socket_pool_base_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698