| 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 24 matching lines...) Expand all Loading... |
| 35 #include "base/task.h" | 35 #include "base/task.h" |
| 36 #include "base/time.h" | 36 #include "base/time.h" |
| 37 #include "base/timer.h" | 37 #include "base/timer.h" |
| 38 #include "net/base/address_list.h" | 38 #include "net/base/address_list.h" |
| 39 #include "net/base/completion_callback.h" | 39 #include "net/base/completion_callback.h" |
| 40 #include "net/base/load_states.h" | 40 #include "net/base/load_states.h" |
| 41 #include "net/base/net_errors.h" | 41 #include "net/base/net_errors.h" |
| 42 #include "net/base/net_log.h" | 42 #include "net/base/net_log.h" |
| 43 #include "net/base/network_change_notifier.h" | 43 #include "net/base/network_change_notifier.h" |
| 44 #include "net/base/request_priority.h" | 44 #include "net/base/request_priority.h" |
| 45 #include "net/socket/client_socket.h" | |
| 46 #include "net/socket/client_socket_pool.h" | 45 #include "net/socket/client_socket_pool.h" |
| 46 #include "net/socket/stream_socket.h" |
| 47 | 47 |
| 48 namespace net { | 48 namespace net { |
| 49 | 49 |
| 50 class ClientSocketHandle; | 50 class ClientSocketHandle; |
| 51 | 51 |
| 52 // ConnectJob provides an abstract interface for "connecting" a socket. | 52 // ConnectJob provides an abstract interface for "connecting" a socket. |
| 53 // The connection may involve host resolution, tcp connection, ssl connection, | 53 // The connection may involve host resolution, tcp connection, ssl connection, |
| 54 // etc. | 54 // etc. |
| 55 class ConnectJob { | 55 class ConnectJob { |
| 56 public: | 56 public: |
| (...skipping 25 matching lines...) Expand all Loading... |
| 82 } | 82 } |
| 83 | 83 |
| 84 // Initialized by the ClientSocketPoolBaseHelper. | 84 // Initialized by the ClientSocketPoolBaseHelper. |
| 85 // TODO(willchan): Move most of the constructor arguments over here. We | 85 // TODO(willchan): Move most of the constructor arguments over here. We |
| 86 // shouldn't give the ConnectJobFactory (subclasses) the ability to screw up | 86 // shouldn't give the ConnectJobFactory (subclasses) the ability to screw up |
| 87 // the initialization. | 87 // the initialization. |
| 88 void Initialize(bool is_preconnect); | 88 void Initialize(bool is_preconnect); |
| 89 | 89 |
| 90 // Releases |socket_| to the client. On connection error, this should return | 90 // Releases |socket_| to the client. On connection error, this should return |
| 91 // NULL. | 91 // NULL. |
| 92 ClientSocket* ReleaseSocket() { return socket_.release(); } | 92 StreamSocket* ReleaseSocket() { return socket_.release(); } |
| 93 | 93 |
| 94 // Begins connecting the socket. Returns OK on success, ERR_IO_PENDING if it | 94 // Begins connecting the socket. Returns OK on success, ERR_IO_PENDING if it |
| 95 // cannot complete synchronously without blocking, or another net error code | 95 // cannot complete synchronously without blocking, or another net error code |
| 96 // on error. In asynchronous completion, the ConnectJob will notify | 96 // on error. In asynchronous completion, the ConnectJob will notify |
| 97 // |delegate_| via OnConnectJobComplete. In both asynchronous and synchronous | 97 // |delegate_| via OnConnectJobComplete. In both asynchronous and synchronous |
| 98 // completion, ReleaseSocket() can be called to acquire the connected socket | 98 // completion, ReleaseSocket() can be called to acquire the connected socket |
| 99 // if it succeeded. | 99 // if it succeeded. |
| 100 int Connect(); | 100 int Connect(); |
| 101 | 101 |
| 102 // Precondition: is_unused_preconnect() must be true. Marks the job as a | 102 // Precondition: is_unused_preconnect() must be true. Marks the job as a |
| 103 // used preconnect job. | 103 // used preconnect job. |
| 104 void UseForNormalRequest(); | 104 void UseForNormalRequest(); |
| 105 | 105 |
| 106 virtual LoadState GetLoadState() const = 0; | 106 virtual LoadState GetLoadState() const = 0; |
| 107 | 107 |
| 108 // If Connect returns an error (or OnConnectJobComplete reports an error | 108 // If Connect returns an error (or OnConnectJobComplete reports an error |
| 109 // result) this method will be called, allowing the pool to add | 109 // result) this method will be called, allowing the pool to add |
| 110 // additional error state to the ClientSocketHandle (post late-binding). | 110 // additional error state to the ClientSocketHandle (post late-binding). |
| 111 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {} | 111 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {} |
| 112 | 112 |
| 113 const BoundNetLog& net_log() const { return net_log_; } | 113 const BoundNetLog& net_log() const { return net_log_; } |
| 114 | 114 |
| 115 protected: | 115 protected: |
| 116 void set_socket(ClientSocket* socket); | 116 void set_socket(StreamSocket* socket); |
| 117 ClientSocket* socket() { return socket_.get(); } | 117 StreamSocket* socket() { return socket_.get(); } |
| 118 void NotifyDelegateOfCompletion(int rv); | 118 void NotifyDelegateOfCompletion(int rv); |
| 119 void ResetTimer(base::TimeDelta remainingTime); | 119 void ResetTimer(base::TimeDelta remainingTime); |
| 120 | 120 |
| 121 private: | 121 private: |
| 122 enum PreconnectState { | 122 enum PreconnectState { |
| 123 NOT_PRECONNECT, | 123 NOT_PRECONNECT, |
| 124 UNUSED_PRECONNECT, | 124 UNUSED_PRECONNECT, |
| 125 USED_PRECONNECT, | 125 USED_PRECONNECT, |
| 126 }; | 126 }; |
| 127 | 127 |
| 128 virtual int ConnectInternal() = 0; | 128 virtual int ConnectInternal() = 0; |
| 129 | 129 |
| 130 void LogConnectStart(); | 130 void LogConnectStart(); |
| 131 void LogConnectCompletion(int net_error); | 131 void LogConnectCompletion(int net_error); |
| 132 | 132 |
| 133 // Alerts the delegate that the ConnectJob has timed out. | 133 // Alerts the delegate that the ConnectJob has timed out. |
| 134 void OnTimeout(); | 134 void OnTimeout(); |
| 135 | 135 |
| 136 const std::string group_name_; | 136 const std::string group_name_; |
| 137 const base::TimeDelta timeout_duration_; | 137 const base::TimeDelta timeout_duration_; |
| 138 // Timer to abort jobs that take too long. | 138 // Timer to abort jobs that take too long. |
| 139 base::OneShotTimer<ConnectJob> timer_; | 139 base::OneShotTimer<ConnectJob> timer_; |
| 140 Delegate* delegate_; | 140 Delegate* delegate_; |
| 141 scoped_ptr<ClientSocket> socket_; | 141 scoped_ptr<StreamSocket> socket_; |
| 142 BoundNetLog net_log_; | 142 BoundNetLog net_log_; |
| 143 // A ConnectJob is idle until Connect() has been called. | 143 // A ConnectJob is idle until Connect() has been called. |
| 144 bool idle_; | 144 bool idle_; |
| 145 PreconnectState preconnect_state_; | 145 PreconnectState preconnect_state_; |
| 146 | 146 |
| 147 DISALLOW_COPY_AND_ASSIGN(ConnectJob); | 147 DISALLOW_COPY_AND_ASSIGN(ConnectJob); |
| 148 }; | 148 }; |
| 149 | 149 |
| 150 namespace internal { | 150 namespace internal { |
| 151 | 151 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 void RequestSockets(const std::string& group_name, | 229 void RequestSockets(const std::string& group_name, |
| 230 const Request& request, | 230 const Request& request, |
| 231 int num_sockets); | 231 int num_sockets); |
| 232 | 232 |
| 233 // See ClientSocketPool::CancelRequest for documentation on this function. | 233 // See ClientSocketPool::CancelRequest for documentation on this function. |
| 234 void CancelRequest(const std::string& group_name, | 234 void CancelRequest(const std::string& group_name, |
| 235 ClientSocketHandle* handle); | 235 ClientSocketHandle* handle); |
| 236 | 236 |
| 237 // See ClientSocketPool::ReleaseSocket for documentation on this function. | 237 // See ClientSocketPool::ReleaseSocket for documentation on this function. |
| 238 void ReleaseSocket(const std::string& group_name, | 238 void ReleaseSocket(const std::string& group_name, |
| 239 ClientSocket* socket, | 239 StreamSocket* socket, |
| 240 int id); | 240 int id); |
| 241 | 241 |
| 242 // See ClientSocketPool::Flush for documentation on this function. | 242 // See ClientSocketPool::Flush for documentation on this function. |
| 243 void Flush(); | 243 void Flush(); |
| 244 | 244 |
| 245 // See ClientSocketPool::CloseIdleSockets for documentation on this function. | 245 // See ClientSocketPool::CloseIdleSockets for documentation on this function. |
| 246 void CloseIdleSockets(); | 246 void CloseIdleSockets(); |
| 247 | 247 |
| 248 // See ClientSocketPool::IdleSocketCount() for documentation on this function. | 248 // See ClientSocketPool::IdleSocketCount() for documentation on this function. |
| 249 int idle_socket_count() const { | 249 int idle_socket_count() const { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 // An idle socket should be removed if it can't be reused, or has been idle | 307 // An idle socket should be removed if it can't be reused, or has been idle |
| 308 // for too long. |now| is the current time value (TimeTicks::Now()). | 308 // for too long. |now| is the current time value (TimeTicks::Now()). |
| 309 // |timeout| is the length of time to wait before timing out an idle socket. | 309 // |timeout| is the length of time to wait before timing out an idle socket. |
| 310 // | 310 // |
| 311 // An idle socket can't be reused if it is disconnected or has received | 311 // An idle socket can't be reused if it is disconnected or has received |
| 312 // data unexpectedly (hence no longer idle). The unread data would be | 312 // data unexpectedly (hence no longer idle). The unread data would be |
| 313 // mistaken for the beginning of the next response if we were to reuse the | 313 // mistaken for the beginning of the next response if we were to reuse the |
| 314 // socket for a new request. | 314 // socket for a new request. |
| 315 bool ShouldCleanup(base::TimeTicks now, base::TimeDelta timeout) const; | 315 bool ShouldCleanup(base::TimeTicks now, base::TimeDelta timeout) const; |
| 316 | 316 |
| 317 ClientSocket* socket; | 317 StreamSocket* socket; |
| 318 base::TimeTicks start_time; | 318 base::TimeTicks start_time; |
| 319 }; | 319 }; |
| 320 | 320 |
| 321 typedef std::deque<const Request* > RequestQueue; | 321 typedef std::deque<const Request* > RequestQueue; |
| 322 typedef std::map<const ClientSocketHandle*, const Request*> RequestMap; | 322 typedef std::map<const ClientSocketHandle*, const Request*> RequestMap; |
| 323 | 323 |
| 324 // A Group is allocated per group_name when there are idle sockets or pending | 324 // A Group is allocated per group_name when there are idle sockets or pending |
| 325 // requests. Otherwise, the Group object is removed from the map. | 325 // requests. Otherwise, the Group object is removed from the map. |
| 326 // |active_socket_count| tracks the number of sockets held by clients. | 326 // |active_socket_count| tracks the number of sockets held by clients. |
| 327 class Group { | 327 class Group { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 // Removes |job| from |connect_job_set_|. Also updates |group| if non-NULL. | 438 // Removes |job| from |connect_job_set_|. Also updates |group| if non-NULL. |
| 439 void RemoveConnectJob(ConnectJob* job, Group* group); | 439 void RemoveConnectJob(ConnectJob* job, Group* group); |
| 440 | 440 |
| 441 // Tries to see if we can handle any more requests for |group|. | 441 // Tries to see if we can handle any more requests for |group|. |
| 442 void OnAvailableSocketSlot(const std::string& group_name, Group* group); | 442 void OnAvailableSocketSlot(const std::string& group_name, Group* group); |
| 443 | 443 |
| 444 // Process a pending socket request for a group. | 444 // Process a pending socket request for a group. |
| 445 void ProcessPendingRequest(const std::string& group_name, Group* group); | 445 void ProcessPendingRequest(const std::string& group_name, Group* group); |
| 446 | 446 |
| 447 // Assigns |socket| to |handle| and updates |group|'s counters appropriately. | 447 // Assigns |socket| to |handle| and updates |group|'s counters appropriately. |
| 448 void HandOutSocket(ClientSocket* socket, | 448 void HandOutSocket(StreamSocket* socket, |
| 449 bool reused, | 449 bool reused, |
| 450 ClientSocketHandle* handle, | 450 ClientSocketHandle* handle, |
| 451 base::TimeDelta time_idle, | 451 base::TimeDelta time_idle, |
| 452 Group* group, | 452 Group* group, |
| 453 const BoundNetLog& net_log); | 453 const BoundNetLog& net_log); |
| 454 | 454 |
| 455 // Adds |socket| to the list of idle sockets for |group|. | 455 // Adds |socket| to the list of idle sockets for |group|. |
| 456 void AddIdleSocket(ClientSocket* socket, Group* group); | 456 void AddIdleSocket(StreamSocket* socket, Group* group); |
| 457 | 457 |
| 458 // Iterates through |group_map_|, canceling all ConnectJobs and deleting | 458 // Iterates through |group_map_|, canceling all ConnectJobs and deleting |
| 459 // groups if they are no longer needed. | 459 // groups if they are no longer needed. |
| 460 void CancelAllConnectJobs(); | 460 void CancelAllConnectJobs(); |
| 461 | 461 |
| 462 // Iterates through |group_map_|, posting ERR_ABORTED callbacks for all | 462 // Iterates through |group_map_|, posting ERR_ABORTED callbacks for all |
| 463 // requests, and then deleting groups if they are no longer needed. | 463 // requests, and then deleting groups if they are no longer needed. |
| 464 void AbortAllRequests(); | 464 void AbortAllRequests(); |
| 465 | 465 |
| 466 // Returns true if we can't create any more sockets due to the total limit. | 466 // Returns true if we can't create any more sockets due to the total limit. |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 params, | 648 params, |
| 649 net_log); | 649 net_log); |
| 650 helper_.RequestSockets(group_name, request, num_sockets); | 650 helper_.RequestSockets(group_name, request, num_sockets); |
| 651 } | 651 } |
| 652 | 652 |
| 653 void CancelRequest(const std::string& group_name, | 653 void CancelRequest(const std::string& group_name, |
| 654 ClientSocketHandle* handle) { | 654 ClientSocketHandle* handle) { |
| 655 return helper_.CancelRequest(group_name, handle); | 655 return helper_.CancelRequest(group_name, handle); |
| 656 } | 656 } |
| 657 | 657 |
| 658 void ReleaseSocket(const std::string& group_name, ClientSocket* socket, | 658 void ReleaseSocket(const std::string& group_name, StreamSocket* socket, |
| 659 int id) { | 659 int id) { |
| 660 return helper_.ReleaseSocket(group_name, socket, id); | 660 return helper_.ReleaseSocket(group_name, socket, id); |
| 661 } | 661 } |
| 662 | 662 |
| 663 void CloseIdleSockets() { return helper_.CloseIdleSockets(); } | 663 void CloseIdleSockets() { return helper_.CloseIdleSockets(); } |
| 664 | 664 |
| 665 int idle_socket_count() const { return helper_.idle_socket_count(); } | 665 int idle_socket_count() const { return helper_.idle_socket_count(); } |
| 666 | 666 |
| 667 int IdleSocketCountInGroup(const std::string& group_name) const { | 667 int IdleSocketCountInGroup(const std::string& group_name) const { |
| 668 return helper_.IdleSocketCountInGroup(group_name); | 668 return helper_.IdleSocketCountInGroup(group_name); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 // Histograms for the pool | 745 // Histograms for the pool |
| 746 ClientSocketPoolHistograms* const histograms_; | 746 ClientSocketPoolHistograms* const histograms_; |
| 747 internal::ClientSocketPoolBaseHelper helper_; | 747 internal::ClientSocketPoolBaseHelper helper_; |
| 748 | 748 |
| 749 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); | 749 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); |
| 750 }; | 750 }; |
| 751 | 751 |
| 752 } // namespace net | 752 } // namespace net |
| 753 | 753 |
| 754 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ | 754 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ |
| OLD | NEW |