| OLD | NEW |
| 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 // 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 21 matching lines...) Expand all Loading... |
| 32 #include "base/ref_counted.h" | 32 #include "base/ref_counted.h" |
| 33 #include "base/scoped_ptr.h" | 33 #include "base/scoped_ptr.h" |
| 34 #include "base/task.h" | 34 #include "base/task.h" |
| 35 #include "base/time.h" | 35 #include "base/time.h" |
| 36 #include "base/timer.h" | 36 #include "base/timer.h" |
| 37 #include "net/base/address_list.h" | 37 #include "net/base/address_list.h" |
| 38 #include "net/base/completion_callback.h" | 38 #include "net/base/completion_callback.h" |
| 39 #include "net/base/load_states.h" | 39 #include "net/base/load_states.h" |
| 40 #include "net/base/net_errors.h" | 40 #include "net/base/net_errors.h" |
| 41 #include "net/base/net_log.h" | 41 #include "net/base/net_log.h" |
| 42 #include "net/base/network_change_notifier.h" |
| 42 #include "net/base/request_priority.h" | 43 #include "net/base/request_priority.h" |
| 43 #include "net/socket/client_socket.h" | 44 #include "net/socket/client_socket.h" |
| 44 #include "net/socket/client_socket_pool.h" | 45 #include "net/socket/client_socket_pool.h" |
| 45 | 46 |
| 46 namespace net { | 47 namespace net { |
| 47 | 48 |
| 48 class ClientSocketHandle; | 49 class ClientSocketHandle; |
| 49 | 50 |
| 50 // ConnectJob provides an abstract interface for "connecting" a socket. | 51 // ConnectJob provides an abstract interface for "connecting" a socket. |
| 51 // The connection may involve host resolution, tcp connection, ssl connection, | 52 // The connection may involve host resolution, tcp connection, ssl connection, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 | 115 |
| 115 namespace internal { | 116 namespace internal { |
| 116 | 117 |
| 117 // ClientSocketPoolBaseHelper is an internal class that implements almost all | 118 // ClientSocketPoolBaseHelper is an internal class that implements almost all |
| 118 // the functionality from ClientSocketPoolBase without using templates. | 119 // the functionality from ClientSocketPoolBase without using templates. |
| 119 // ClientSocketPoolBase adds templated definitions built on top of | 120 // ClientSocketPoolBase adds templated definitions built on top of |
| 120 // ClientSocketPoolBaseHelper. This class is not for external use, please use | 121 // ClientSocketPoolBaseHelper. This class is not for external use, please use |
| 121 // ClientSocketPoolBase instead. | 122 // ClientSocketPoolBase instead. |
| 122 class ClientSocketPoolBaseHelper | 123 class ClientSocketPoolBaseHelper |
| 123 : public base::RefCounted<ClientSocketPoolBaseHelper>, | 124 : public base::RefCounted<ClientSocketPoolBaseHelper>, |
| 124 public ConnectJob::Delegate { | 125 public ConnectJob::Delegate, |
| 126 public NetworkChangeNotifier::Observer { |
| 125 public: | 127 public: |
| 126 class Request { | 128 class Request { |
| 127 public: | 129 public: |
| 128 Request(ClientSocketHandle* handle, | 130 Request(ClientSocketHandle* handle, |
| 129 CompletionCallback* callback, | 131 CompletionCallback* callback, |
| 130 RequestPriority priority, | 132 RequestPriority priority, |
| 131 const BoundNetLog& net_log); | 133 const BoundNetLog& net_log); |
| 132 | 134 |
| 133 virtual ~Request(); | 135 virtual ~Request(); |
| 134 | 136 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 161 | 163 |
| 162 private: | 164 private: |
| 163 DISALLOW_COPY_AND_ASSIGN(ConnectJobFactory); | 165 DISALLOW_COPY_AND_ASSIGN(ConnectJobFactory); |
| 164 }; | 166 }; |
| 165 | 167 |
| 166 ClientSocketPoolBaseHelper( | 168 ClientSocketPoolBaseHelper( |
| 167 int max_sockets, | 169 int max_sockets, |
| 168 int max_sockets_per_group, | 170 int max_sockets_per_group, |
| 169 base::TimeDelta unused_idle_socket_timeout, | 171 base::TimeDelta unused_idle_socket_timeout, |
| 170 base::TimeDelta used_idle_socket_timeout, | 172 base::TimeDelta used_idle_socket_timeout, |
| 171 ConnectJobFactory* connect_job_factory); | 173 ConnectJobFactory* connect_job_factory, |
| 174 NetworkChangeNotifier* network_change_notifier); |
| 172 | 175 |
| 173 // See ClientSocketPool::RequestSocket for documentation on this function. | 176 // See ClientSocketPool::RequestSocket for documentation on this function. |
| 174 // Note that |request| must be heap allocated. If ERR_IO_PENDING is returned, | 177 // Note that |request| must be heap allocated. If ERR_IO_PENDING is returned, |
| 175 // then ClientSocketPoolBaseHelper takes ownership of |request|. | 178 // then ClientSocketPoolBaseHelper takes ownership of |request|. |
| 176 int RequestSocket(const std::string& group_name, const Request* request); | 179 int RequestSocket(const std::string& group_name, const Request* request); |
| 177 | 180 |
| 178 // See ClientSocketPool::CancelRequest for documentation on this function. | 181 // See ClientSocketPool::CancelRequest for documentation on this function. |
| 179 void CancelRequest(const std::string& group_name, | 182 void CancelRequest(const std::string& group_name, |
| 180 const ClientSocketHandle* handle); | 183 const ClientSocketHandle* handle); |
| 181 | 184 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 201 | 204 |
| 202 int ConnectRetryIntervalMs() const { | 205 int ConnectRetryIntervalMs() const { |
| 203 // TODO(mbelshe): Make this tuned dynamically based on measured RTT. | 206 // TODO(mbelshe): Make this tuned dynamically based on measured RTT. |
| 204 // For now, just use the max retry interval. | 207 // For now, just use the max retry interval. |
| 205 return ClientSocketPool::kMaxConnectRetryIntervalMs; | 208 return ClientSocketPool::kMaxConnectRetryIntervalMs; |
| 206 } | 209 } |
| 207 | 210 |
| 208 // ConnectJob::Delegate methods: | 211 // ConnectJob::Delegate methods: |
| 209 virtual void OnConnectJobComplete(int result, ConnectJob* job); | 212 virtual void OnConnectJobComplete(int result, ConnectJob* job); |
| 210 | 213 |
| 214 // NetworkChangeNotifier::Observer methods: |
| 215 virtual void OnIPAddressChanged(); |
| 216 |
| 211 // For testing. | 217 // For testing. |
| 212 bool may_have_stalled_group() const { return may_have_stalled_group_; } | 218 bool may_have_stalled_group() const { return may_have_stalled_group_; } |
| 213 | 219 |
| 214 int NumConnectJobsInGroup(const std::string& group_name) const { | 220 int NumConnectJobsInGroup(const std::string& group_name) const { |
| 215 return group_map_.find(group_name)->second.jobs.size(); | 221 return group_map_.find(group_name)->second.jobs.size(); |
| 216 } | 222 } |
| 217 | 223 |
| 218 // Closes all idle sockets if |force| is true. Else, only closes idle | 224 // Closes all idle sockets if |force| is true. Else, only closes idle |
| 219 // sockets that timed out or can't be reused. Made public for testing. | 225 // sockets that timed out or can't be reused. Made public for testing. |
| 220 void CleanupIdleSockets(bool force); | 226 void CleanupIdleSockets(bool force); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 // |max_sockets_per_group_| limit. So choosing the next request involves | 427 // |max_sockets_per_group_| limit. So choosing the next request involves |
| 422 // selecting the highest priority request across *all* groups. | 428 // selecting the highest priority request across *all* groups. |
| 423 // | 429 // |
| 424 // Since reaching the maximum number of sockets is an edge case, we make note | 430 // Since reaching the maximum number of sockets is an edge case, we make note |
| 425 // of when it happens, and thus avoid doing the slower "scan all groups" | 431 // of when it happens, and thus avoid doing the slower "scan all groups" |
| 426 // in the common case. | 432 // in the common case. |
| 427 bool may_have_stalled_group_; | 433 bool may_have_stalled_group_; |
| 428 | 434 |
| 429 const scoped_ptr<ConnectJobFactory> connect_job_factory_; | 435 const scoped_ptr<ConnectJobFactory> connect_job_factory_; |
| 430 | 436 |
| 437 NetworkChangeNotifier* const network_change_notifier_; |
| 438 |
| 431 // TODO(vandebo) Remove when backup jobs move to TCPClientSocketPool | 439 // TODO(vandebo) Remove when backup jobs move to TCPClientSocketPool |
| 432 bool backup_jobs_enabled_; | 440 bool backup_jobs_enabled_; |
| 433 | 441 |
| 434 // A factory to pin the backup_job tasks. | 442 // A factory to pin the backup_job tasks. |
| 435 ScopedRunnableMethodFactory<ClientSocketPoolBaseHelper> method_factory_; | 443 ScopedRunnableMethodFactory<ClientSocketPoolBaseHelper> method_factory_; |
| 436 }; | 444 }; |
| 437 | 445 |
| 438 } // namespace internal | 446 } // namespace internal |
| 439 | 447 |
| 440 // The maximum duration, in seconds, to keep unused idle persistent sockets | 448 // The maximum duration, in seconds, to keep unused idle persistent sockets |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 // sockets a "group" can have. |unused_idle_socket_timeout| specifies how | 495 // sockets a "group" can have. |unused_idle_socket_timeout| specifies how |
| 488 // long to leave an unused idle socket open before closing it. | 496 // long to leave an unused idle socket open before closing it. |
| 489 // |used_idle_socket_timeout| specifies how long to leave a previously used | 497 // |used_idle_socket_timeout| specifies how long to leave a previously used |
| 490 // idle socket open before closing it. | 498 // idle socket open before closing it. |
| 491 ClientSocketPoolBase( | 499 ClientSocketPoolBase( |
| 492 int max_sockets, | 500 int max_sockets, |
| 493 int max_sockets_per_group, | 501 int max_sockets_per_group, |
| 494 const std::string& name, | 502 const std::string& name, |
| 495 base::TimeDelta unused_idle_socket_timeout, | 503 base::TimeDelta unused_idle_socket_timeout, |
| 496 base::TimeDelta used_idle_socket_timeout, | 504 base::TimeDelta used_idle_socket_timeout, |
| 497 ConnectJobFactory* connect_job_factory) | 505 ConnectJobFactory* connect_job_factory, |
| 506 NetworkChangeNotifier* network_change_notifier) |
| 498 : name_(name), | 507 : name_(name), |
| 499 helper_(new internal::ClientSocketPoolBaseHelper( | 508 helper_(new internal::ClientSocketPoolBaseHelper( |
| 500 max_sockets, max_sockets_per_group, | 509 max_sockets, max_sockets_per_group, |
| 501 unused_idle_socket_timeout, used_idle_socket_timeout, | 510 unused_idle_socket_timeout, used_idle_socket_timeout, |
| 502 new ConnectJobFactoryAdaptor(connect_job_factory))) {} | 511 new ConnectJobFactoryAdaptor(connect_job_factory), |
| 512 network_change_notifier)) {} |
| 503 | 513 |
| 504 virtual ~ClientSocketPoolBase() {} | 514 virtual ~ClientSocketPoolBase() {} |
| 505 | 515 |
| 506 // These member functions simply forward to ClientSocketPoolBaseHelper. | 516 // These member functions simply forward to ClientSocketPoolBaseHelper. |
| 507 | 517 |
| 508 // RequestSocket bundles up the parameters into a Request and then forwards to | 518 // RequestSocket bundles up the parameters into a Request and then forwards to |
| 509 // ClientSocketPoolBaseHelper::RequestSocket(). Note that the memory | 519 // ClientSocketPoolBaseHelper::RequestSocket(). Note that the memory |
| 510 // ownership is transferred in the asynchronous (ERR_IO_PENDING) case. | 520 // ownership is transferred in the asynchronous (ERR_IO_PENDING) case. |
| 511 int RequestSocket(const std::string& group_name, | 521 int RequestSocket(const std::string& group_name, |
| 512 const SocketParams& params, | 522 const SocketParams& params, |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 // the posting of the task and the execution, then we'll hit the DCHECK that | 622 // the posting of the task and the execution, then we'll hit the DCHECK that |
| 613 // |ClientSocketPoolBaseHelper::group_map_| is empty. | 623 // |ClientSocketPoolBaseHelper::group_map_| is empty. |
| 614 scoped_refptr<internal::ClientSocketPoolBaseHelper> helper_; | 624 scoped_refptr<internal::ClientSocketPoolBaseHelper> helper_; |
| 615 | 625 |
| 616 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); | 626 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); |
| 617 }; | 627 }; |
| 618 | 628 |
| 619 } // namespace net | 629 } // namespace net |
| 620 | 630 |
| 621 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ | 631 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ |
| OLD | NEW |