| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // A ClientSocketPoolBase is used to restrict the number of sockets open at | 5 // A ClientSocketPoolBase is used to restrict the number of sockets open at |
| 6 // a time. It also maintains a list of idle persistent sockets for reuse. | 6 // a time. It also maintains a list of idle persistent sockets for reuse. |
| 7 // Subclasses of ClientSocketPool should compose ClientSocketPoolBase to handle | 7 // Subclasses of ClientSocketPool should compose ClientSocketPoolBase to handle |
| 8 // the core logic of (1) restricting the number of active (connected or | 8 // the core logic of (1) restricting the number of active (connected or |
| 9 // connecting) sockets per "group" (generally speaking, the hostname), (2) | 9 // connecting) sockets per "group" (generally speaking, the hostname), (2) |
| 10 // maintaining a per-group list of idle, persistent sockets for reuse, and (3) | 10 // maintaining a per-group list of idle, persistent sockets for reuse, and (3) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 // | 21 // |
| 22 #ifndef NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ | 22 #ifndef NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ |
| 23 #define NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ | 23 #define NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ |
| 24 #pragma once | 24 #pragma once |
| 25 | 25 |
| 26 #include <deque> | 26 #include <deque> |
| 27 #include <list> | 27 #include <list> |
| 28 #include <map> | 28 #include <map> |
| 29 #include <set> | 29 #include <set> |
| 30 #include <string> | 30 #include <string> |
| 31 #include <vector> |
| 31 | 32 |
| 32 #include "base/basictypes.h" | 33 #include "base/basictypes.h" |
| 33 #include "base/memory/ref_counted.h" | 34 #include "base/memory/ref_counted.h" |
| 34 #include "base/memory/scoped_ptr.h" | 35 #include "base/memory/scoped_ptr.h" |
| 35 #include "base/task.h" | 36 #include "base/task.h" |
| 36 #include "base/time.h" | 37 #include "base/time.h" |
| 37 #include "base/timer.h" | 38 #include "base/timer.h" |
| 38 #include "net/base/address_list.h" | 39 #include "net/base/address_list.h" |
| 39 #include "net/base/completion_callback.h" | 40 #include "net/base/completion_callback.h" |
| 40 #include "net/base/load_states.h" | 41 #include "net/base/load_states.h" |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 | 233 |
| 233 ClientSocketPoolBaseHelper( | 234 ClientSocketPoolBaseHelper( |
| 234 int max_sockets, | 235 int max_sockets, |
| 235 int max_sockets_per_group, | 236 int max_sockets_per_group, |
| 236 base::TimeDelta unused_idle_socket_timeout, | 237 base::TimeDelta unused_idle_socket_timeout, |
| 237 base::TimeDelta used_idle_socket_timeout, | 238 base::TimeDelta used_idle_socket_timeout, |
| 238 ConnectJobFactory* connect_job_factory); | 239 ConnectJobFactory* connect_job_factory); |
| 239 | 240 |
| 240 virtual ~ClientSocketPoolBaseHelper(); | 241 virtual ~ClientSocketPoolBaseHelper(); |
| 241 | 242 |
| 243 // Adds/Removes layered pools. It is expected in the destructor that no |
| 244 // layered pools remain. |
| 245 void AddLayeredPool(LayeredPool* pool); |
| 246 void RemoveLayeredPool(LayeredPool* pool); |
| 247 |
| 242 // See ClientSocketPool::RequestSocket for documentation on this function. | 248 // See ClientSocketPool::RequestSocket for documentation on this function. |
| 243 // ClientSocketPoolBaseHelper takes ownership of |request|, which must be | 249 // ClientSocketPoolBaseHelper takes ownership of |request|, which must be |
| 244 // heap allocated. | 250 // heap allocated. |
| 245 int RequestSocket(const std::string& group_name, const Request* request); | 251 int RequestSocket(const std::string& group_name, const Request* request); |
| 246 | 252 |
| 247 // See ClientSocketPool::RequestSocket for documentation on this function. | 253 // See ClientSocketPool::RequestSocket for documentation on this function. |
| 248 void RequestSockets(const std::string& group_name, | 254 void RequestSockets(const std::string& group_name, |
| 249 const Request& request, | 255 const Request& request, |
| 250 int num_sockets); | 256 int num_sockets); |
| 251 | 257 |
| 252 // See ClientSocketPool::CancelRequest for documentation on this function. | 258 // See ClientSocketPool::CancelRequest for documentation on this function. |
| 253 void CancelRequest(const std::string& group_name, | 259 void CancelRequest(const std::string& group_name, |
| 254 ClientSocketHandle* handle); | 260 ClientSocketHandle* handle); |
| 255 | 261 |
| 256 // See ClientSocketPool::ReleaseSocket for documentation on this function. | 262 // See ClientSocketPool::ReleaseSocket for documentation on this function. |
| 257 void ReleaseSocket(const std::string& group_name, | 263 void ReleaseSocket(const std::string& group_name, |
| 258 StreamSocket* socket, | 264 StreamSocket* socket, |
| 259 int id); | 265 int id); |
| 260 | 266 |
| 261 // See ClientSocketPool::Flush for documentation on this function. | 267 // See ClientSocketPool::Flush for documentation on this function. |
| 262 void Flush(); | 268 void Flush(); |
| 263 | 269 |
| 270 // See ClientSocketPool::IsStalled for documentation on this function. |
| 271 bool IsStalled() const; |
| 272 |
| 264 // See ClientSocketPool::CloseIdleSockets for documentation on this function. | 273 // See ClientSocketPool::CloseIdleSockets for documentation on this function. |
| 265 void CloseIdleSockets(); | 274 void CloseIdleSockets(); |
| 266 | 275 |
| 267 // See ClientSocketPool::IdleSocketCount() for documentation on this function. | 276 // See ClientSocketPool::IdleSocketCount() for documentation on this function. |
| 268 int idle_socket_count() const { | 277 int idle_socket_count() const { |
| 269 return idle_socket_count_; | 278 return idle_socket_count_; |
| 270 } | 279 } |
| 271 | 280 |
| 272 // See ClientSocketPool::IdleSocketCountInGroup() for documentation on this | 281 // See ClientSocketPool::IdleSocketCountInGroup() for documentation on this |
| 273 // function. | 282 // function. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 290 int NumActiveSocketsInGroup(const std::string& group_name) const { | 299 int NumActiveSocketsInGroup(const std::string& group_name) const { |
| 291 return group_map_.find(group_name)->second->active_socket_count(); | 300 return group_map_.find(group_name)->second->active_socket_count(); |
| 292 } | 301 } |
| 293 | 302 |
| 294 bool HasGroup(const std::string& group_name) const; | 303 bool HasGroup(const std::string& group_name) const; |
| 295 | 304 |
| 296 // Closes all idle sockets if |force| is true. Else, only closes idle | 305 // Closes all idle sockets if |force| is true. Else, only closes idle |
| 297 // sockets that timed out or can't be reused. Made public for testing. | 306 // sockets that timed out or can't be reused. Made public for testing. |
| 298 void CleanupIdleSockets(bool force); | 307 void CleanupIdleSockets(bool force); |
| 299 | 308 |
| 309 // Closes one idle socket. Picks the first one encountered. |
| 310 // TODO(willchan): Consider a better algorithm for doing this. Perhaps we |
| 311 // should keep an ordered list of idle sockets, and close them in order. |
| 312 // Requires maintaining more state. It's not clear if it's worth it since |
| 313 // I'm not sure if we hit this situation often. |
| 314 bool CloseOneIdleSocket(); |
| 315 |
| 300 // See ClientSocketPool::GetInfoAsValue for documentation on this function. | 316 // See ClientSocketPool::GetInfoAsValue for documentation on this function. |
| 301 base::DictionaryValue* GetInfoAsValue(const std::string& name, | 317 base::DictionaryValue* GetInfoAsValue(const std::string& name, |
| 302 const std::string& type) const; | 318 const std::string& type) const; |
| 303 | 319 |
| 304 base::TimeDelta ConnectionTimeout() const { | 320 base::TimeDelta ConnectionTimeout() const { |
| 305 return connect_job_factory_->ConnectionTimeout(); | 321 return connect_job_factory_->ConnectionTimeout(); |
| 306 } | 322 } |
| 307 | 323 |
| 308 static bool connect_backup_jobs_enabled(); | 324 static bool connect_backup_jobs_enabled(); |
| 309 static bool set_connect_backup_jobs_enabled(bool enabled); | 325 static bool set_connect_backup_jobs_enabled(bool enabled); |
| 310 | 326 |
| 311 void EnableConnectBackupJobs(); | 327 void EnableConnectBackupJobs(); |
| 312 | 328 |
| 313 // ConnectJob::Delegate methods: | 329 // ConnectJob::Delegate methods: |
| 314 virtual void OnConnectJobComplete(int result, ConnectJob* job); | 330 virtual void OnConnectJobComplete(int result, ConnectJob* job); |
| 315 | 331 |
| 332 // Checks layered pools to see if they can close an idle connection. |
| 333 bool CloseOneIdleConnectionInLayeredPool(); |
| 334 |
| 316 // NetworkChangeNotifier::IPAddressObserver methods: | 335 // NetworkChangeNotifier::IPAddressObserver methods: |
| 317 virtual void OnIPAddressChanged(); | 336 virtual void OnIPAddressChanged(); |
| 318 | 337 |
| 319 private: | 338 private: |
| 320 friend class base::RefCounted<ClientSocketPoolBaseHelper>; | 339 friend class base::RefCounted<ClientSocketPoolBaseHelper>; |
| 321 | 340 |
| 322 // Entry for a persistent socket which became idle at time |start_time|. | 341 // Entry for a persistent socket which became idle at time |start_time|. |
| 323 struct IdleSocket { | 342 struct IdleSocket { |
| 324 IdleSocket() : socket(NULL) {} | 343 IdleSocket() : socket(NULL) {} |
| 325 | 344 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 void RemoveGroup(GroupMap::iterator it); | 458 void RemoveGroup(GroupMap::iterator it); |
| 440 | 459 |
| 441 // Called when the number of idle sockets changes. | 460 // Called when the number of idle sockets changes. |
| 442 void IncrementIdleCount(); | 461 void IncrementIdleCount(); |
| 443 void DecrementIdleCount(); | 462 void DecrementIdleCount(); |
| 444 | 463 |
| 445 // Scans the group map for groups which have an available socket slot and | 464 // Scans the group map for groups which have an available socket slot and |
| 446 // at least one pending request. Returns true if any groups are stalled, and | 465 // at least one pending request. Returns true if any groups are stalled, and |
| 447 // if so, fills |group| and |group_name| with data of the stalled group | 466 // if so, fills |group| and |group_name| with data of the stalled group |
| 448 // having highest priority. | 467 // having highest priority. |
| 449 bool FindTopStalledGroup(Group** group, std::string* group_name); | 468 bool FindTopStalledGroup(Group** group, std::string* group_name) const; |
| 450 | 469 |
| 451 // Called when timer_ fires. This method scans the idle sockets removing | 470 // Called when timer_ fires. This method scans the idle sockets removing |
| 452 // sockets that timed out or can't be reused. | 471 // sockets that timed out or can't be reused. |
| 453 void OnCleanupTimerFired() { | 472 void OnCleanupTimerFired() { |
| 454 CleanupIdleSockets(false); | 473 CleanupIdleSockets(false); |
| 455 } | 474 } |
| 456 | 475 |
| 457 // Removes |job| from |connect_job_set_|. Also updates |group| if non-NULL. | 476 // Removes |job| from |connect_job_set_|. Also updates |group| if non-NULL. |
| 458 void RemoveConnectJob(ConnectJob* job, Group* group); | 477 void RemoveConnectJob(ConnectJob* job, Group* group); |
| 459 | 478 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 int RequestSocketInternal(const std::string& group_name, | 510 int RequestSocketInternal(const std::string& group_name, |
| 492 const Request* request); | 511 const Request* request); |
| 493 | 512 |
| 494 // Assigns an idle socket for the group to the request. | 513 // Assigns an idle socket for the group to the request. |
| 495 // Returns |true| if an idle socket is available, false otherwise. | 514 // Returns |true| if an idle socket is available, false otherwise. |
| 496 bool AssignIdleSocketToGroup(const Request* request, Group* group); | 515 bool AssignIdleSocketToGroup(const Request* request, Group* group); |
| 497 | 516 |
| 498 static void LogBoundConnectJobToRequest( | 517 static void LogBoundConnectJobToRequest( |
| 499 const NetLog::Source& connect_job_source, const Request* request); | 518 const NetLog::Source& connect_job_source, const Request* request); |
| 500 | 519 |
| 501 // Closes one idle socket. Picks the first one encountered. | |
| 502 // TODO(willchan): Consider a better algorithm for doing this. Perhaps we | |
| 503 // should keep an ordered list of idle sockets, and close them in order. | |
| 504 // Requires maintaining more state. It's not clear if it's worth it since | |
| 505 // I'm not sure if we hit this situation often. | |
| 506 void CloseOneIdleSocket(); | |
| 507 | |
| 508 // Same as CloseOneIdleSocket() except it won't close an idle socket in | 520 // Same as CloseOneIdleSocket() except it won't close an idle socket in |
| 509 // |group|. If |group| is NULL, it is ignored. Returns true if it closed a | 521 // |group|. If |group| is NULL, it is ignored. Returns true if it closed a |
| 510 // socket. | 522 // socket. |
| 511 bool CloseOneIdleSocketExceptInGroup(const Group* group); | 523 bool CloseOneIdleSocketExceptInGroup(const Group* group); |
| 512 | 524 |
| 513 // Checks if there are stalled socket groups that should be notified | 525 // Checks if there are stalled socket groups that should be notified |
| 514 // for possible wakeup. | 526 // for possible wakeup. |
| 515 void CheckForStalledSocketGroups(); | 527 void CheckForStalledSocketGroups(); |
| 516 | 528 |
| 517 // Posts a task to call InvokeUserCallback() on the next iteration through the | 529 // Posts a task to call InvokeUserCallback() on the next iteration through the |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 const scoped_ptr<ConnectJobFactory> connect_job_factory_; | 571 const scoped_ptr<ConnectJobFactory> connect_job_factory_; |
| 560 | 572 |
| 561 // TODO(vandebo) Remove when backup jobs move to TransportClientSocketPool | 573 // TODO(vandebo) Remove when backup jobs move to TransportClientSocketPool |
| 562 bool connect_backup_jobs_enabled_; | 574 bool connect_backup_jobs_enabled_; |
| 563 | 575 |
| 564 // A unique id for the pool. It gets incremented every time we Flush() the | 576 // A unique id for the pool. It gets incremented every time we Flush() the |
| 565 // pool. This is so that when sockets get released back to the pool, we can | 577 // pool. This is so that when sockets get released back to the pool, we can |
| 566 // make sure that they are discarded rather than reused. | 578 // make sure that they are discarded rather than reused. |
| 567 int pool_generation_number_; | 579 int pool_generation_number_; |
| 568 | 580 |
| 581 std::set<LayeredPool*> higher_layer_pools_; |
| 582 |
| 569 ScopedRunnableMethodFactory<ClientSocketPoolBaseHelper> method_factory_; | 583 ScopedRunnableMethodFactory<ClientSocketPoolBaseHelper> method_factory_; |
| 570 | 584 |
| 571 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBaseHelper); | 585 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBaseHelper); |
| 572 }; | 586 }; |
| 573 | 587 |
| 574 } // namespace internal | 588 } // namespace internal |
| 575 | 589 |
| 576 template <typename SocketParams> | 590 template <typename SocketParams> |
| 577 class ClientSocketPoolBase { | 591 class ClientSocketPoolBase { |
| 578 public: | 592 public: |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 base::TimeDelta used_idle_socket_timeout, | 639 base::TimeDelta used_idle_socket_timeout, |
| 626 ConnectJobFactory* connect_job_factory) | 640 ConnectJobFactory* connect_job_factory) |
| 627 : histograms_(histograms), | 641 : histograms_(histograms), |
| 628 helper_(max_sockets, max_sockets_per_group, | 642 helper_(max_sockets, max_sockets_per_group, |
| 629 unused_idle_socket_timeout, used_idle_socket_timeout, | 643 unused_idle_socket_timeout, used_idle_socket_timeout, |
| 630 new ConnectJobFactoryAdaptor(connect_job_factory)) {} | 644 new ConnectJobFactoryAdaptor(connect_job_factory)) {} |
| 631 | 645 |
| 632 virtual ~ClientSocketPoolBase() {} | 646 virtual ~ClientSocketPoolBase() {} |
| 633 | 647 |
| 634 // These member functions simply forward to ClientSocketPoolBaseHelper. | 648 // These member functions simply forward to ClientSocketPoolBaseHelper. |
| 649 void AddLayeredPool(LayeredPool* pool) { |
| 650 helper_.AddLayeredPool(pool); |
| 651 } |
| 652 |
| 653 void RemoveLayeredPool(LayeredPool* pool) { |
| 654 helper_.RemoveLayeredPool(pool); |
| 655 } |
| 635 | 656 |
| 636 // RequestSocket bundles up the parameters into a Request and then forwards to | 657 // RequestSocket bundles up the parameters into a Request and then forwards to |
| 637 // ClientSocketPoolBaseHelper::RequestSocket(). | 658 // ClientSocketPoolBaseHelper::RequestSocket(). |
| 638 int RequestSocket(const std::string& group_name, | 659 int RequestSocket(const std::string& group_name, |
| 639 const scoped_refptr<SocketParams>& params, | 660 const scoped_refptr<SocketParams>& params, |
| 640 RequestPriority priority, | 661 RequestPriority priority, |
| 641 ClientSocketHandle* handle, | 662 ClientSocketHandle* handle, |
| 642 OldCompletionCallback* callback, | 663 OldCompletionCallback* callback, |
| 643 const BoundNetLog& net_log) { | 664 const BoundNetLog& net_log) { |
| 644 Request* request = | 665 Request* request = |
| (...skipping 24 matching lines...) Expand all Loading... |
| 669 void CancelRequest(const std::string& group_name, | 690 void CancelRequest(const std::string& group_name, |
| 670 ClientSocketHandle* handle) { | 691 ClientSocketHandle* handle) { |
| 671 return helper_.CancelRequest(group_name, handle); | 692 return helper_.CancelRequest(group_name, handle); |
| 672 } | 693 } |
| 673 | 694 |
| 674 void ReleaseSocket(const std::string& group_name, StreamSocket* socket, | 695 void ReleaseSocket(const std::string& group_name, StreamSocket* socket, |
| 675 int id) { | 696 int id) { |
| 676 return helper_.ReleaseSocket(group_name, socket, id); | 697 return helper_.ReleaseSocket(group_name, socket, id); |
| 677 } | 698 } |
| 678 | 699 |
| 700 void Flush() { helper_.Flush(); } |
| 701 |
| 702 bool IsStalled() const { return helper_.IsStalled(); } |
| 703 |
| 679 void CloseIdleSockets() { return helper_.CloseIdleSockets(); } | 704 void CloseIdleSockets() { return helper_.CloseIdleSockets(); } |
| 680 | 705 |
| 681 int idle_socket_count() const { return helper_.idle_socket_count(); } | 706 int idle_socket_count() const { return helper_.idle_socket_count(); } |
| 682 | 707 |
| 683 int IdleSocketCountInGroup(const std::string& group_name) const { | 708 int IdleSocketCountInGroup(const std::string& group_name) const { |
| 684 return helper_.IdleSocketCountInGroup(group_name); | 709 return helper_.IdleSocketCountInGroup(group_name); |
| 685 } | 710 } |
| 686 | 711 |
| 687 LoadState GetLoadState(const std::string& group_name, | 712 LoadState GetLoadState(const std::string& group_name, |
| 688 const ClientSocketHandle* handle) const { | 713 const ClientSocketHandle* handle) const { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 717 base::TimeDelta ConnectionTimeout() const { | 742 base::TimeDelta ConnectionTimeout() const { |
| 718 return helper_.ConnectionTimeout(); | 743 return helper_.ConnectionTimeout(); |
| 719 } | 744 } |
| 720 | 745 |
| 721 ClientSocketPoolHistograms* histograms() const { | 746 ClientSocketPoolHistograms* histograms() const { |
| 722 return histograms_; | 747 return histograms_; |
| 723 } | 748 } |
| 724 | 749 |
| 725 void EnableConnectBackupJobs() { helper_.EnableConnectBackupJobs(); } | 750 void EnableConnectBackupJobs() { helper_.EnableConnectBackupJobs(); } |
| 726 | 751 |
| 727 void Flush() { helper_.Flush(); } | 752 bool CloseOneIdleSocket() { return helper_.CloseOneIdleSocket(); } |
| 753 |
| 754 bool CloseOneIdleConnectionInLayeredPool() { |
| 755 return helper_.CloseOneIdleConnectionInLayeredPool(); |
| 756 } |
| 728 | 757 |
| 729 private: | 758 private: |
| 730 // This adaptor class exists to bridge the | 759 // This adaptor class exists to bridge the |
| 731 // internal::ClientSocketPoolBaseHelper::ConnectJobFactory and | 760 // internal::ClientSocketPoolBaseHelper::ConnectJobFactory and |
| 732 // ClientSocketPoolBase::ConnectJobFactory types, allowing clients to use the | 761 // ClientSocketPoolBase::ConnectJobFactory types, allowing clients to use the |
| 733 // typesafe ClientSocketPoolBase::ConnectJobFactory, rather than having to | 762 // typesafe ClientSocketPoolBase::ConnectJobFactory, rather than having to |
| 734 // static_cast themselves. | 763 // static_cast themselves. |
| 735 class ConnectJobFactoryAdaptor | 764 class ConnectJobFactoryAdaptor |
| 736 : public internal::ClientSocketPoolBaseHelper::ConnectJobFactory { | 765 : public internal::ClientSocketPoolBaseHelper::ConnectJobFactory { |
| 737 public: | 766 public: |
| (...skipping 23 matching lines...) Expand all Loading... |
| 761 // Histograms for the pool | 790 // Histograms for the pool |
| 762 ClientSocketPoolHistograms* const histograms_; | 791 ClientSocketPoolHistograms* const histograms_; |
| 763 internal::ClientSocketPoolBaseHelper helper_; | 792 internal::ClientSocketPoolBaseHelper helper_; |
| 764 | 793 |
| 765 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); | 794 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); |
| 766 }; | 795 }; |
| 767 | 796 |
| 768 } // namespace net | 797 } // namespace net |
| 769 | 798 |
| 770 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ | 799 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ |
| OLD | NEW |