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 |