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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 // cannot complete synchronously without blocking, or another net error code | 84 // cannot complete synchronously without blocking, or another net error code |
85 // on error. In asynchronous completion, the ConnectJob will notify | 85 // on error. In asynchronous completion, the ConnectJob will notify |
86 // |delegate_| via OnConnectJobComplete. In both asynchronous and synchronous | 86 // |delegate_| via OnConnectJobComplete. In both asynchronous and synchronous |
87 // completion, ReleaseSocket() can be called to acquire the connected socket | 87 // completion, ReleaseSocket() can be called to acquire the connected socket |
88 // if it succeeded. | 88 // if it succeeded. |
89 int Connect(); | 89 int Connect(); |
90 | 90 |
91 virtual LoadState GetLoadState() const = 0; | 91 virtual LoadState GetLoadState() const = 0; |
92 | 92 |
93 protected: | 93 protected: |
94 void set_socket(ClientSocket* socket) { socket_.reset(socket); } | 94 void set_socket(ClientSocket* socket); |
95 ClientSocket* socket() { return socket_.get(); } | 95 ClientSocket* socket() { return socket_.get(); } |
96 void NotifyDelegateOfCompletion(int rv); | 96 void NotifyDelegateOfCompletion(int rv); |
97 void ResetTimer(base::TimeDelta remainingTime); | 97 void ResetTimer(base::TimeDelta remainingTime); |
98 | 98 |
99 private: | 99 private: |
100 virtual int ConnectInternal() = 0; | 100 virtual int ConnectInternal() = 0; |
101 | 101 |
| 102 void LogConnectStart(); |
| 103 void LogConnectCompletion(int net_error); |
| 104 |
102 // Alerts the delegate that the ConnectJob has timed out. | 105 // Alerts the delegate that the ConnectJob has timed out. |
103 void OnTimeout(); | 106 void OnTimeout(); |
104 | 107 |
105 const std::string group_name_; | 108 const std::string group_name_; |
106 const base::TimeDelta timeout_duration_; | 109 const base::TimeDelta timeout_duration_; |
107 // Timer to abort jobs that take too long. | 110 // Timer to abort jobs that take too long. |
108 base::OneShotTimer<ConnectJob> timer_; | 111 base::OneShotTimer<ConnectJob> timer_; |
109 Delegate* delegate_; | 112 Delegate* delegate_; |
110 scoped_ptr<ClientSocket> socket_; | 113 scoped_ptr<ClientSocket> socket_; |
111 BoundNetLog net_log_; | 114 BoundNetLog net_log_; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 }; | 154 }; |
152 | 155 |
153 class ConnectJobFactory { | 156 class ConnectJobFactory { |
154 public: | 157 public: |
155 ConnectJobFactory() {} | 158 ConnectJobFactory() {} |
156 virtual ~ConnectJobFactory() {} | 159 virtual ~ConnectJobFactory() {} |
157 | 160 |
158 virtual ConnectJob* NewConnectJob( | 161 virtual ConnectJob* NewConnectJob( |
159 const std::string& group_name, | 162 const std::string& group_name, |
160 const Request& request, | 163 const Request& request, |
161 ConnectJob::Delegate* delegate, | 164 ConnectJob::Delegate* delegate) const = 0; |
162 const BoundNetLog& net_log) const = 0; | |
163 | 165 |
164 virtual base::TimeDelta ConnectionTimeout() const = 0; | 166 virtual base::TimeDelta ConnectionTimeout() const = 0; |
165 | 167 |
166 private: | 168 private: |
167 DISALLOW_COPY_AND_ASSIGN(ConnectJobFactory); | 169 DISALLOW_COPY_AND_ASSIGN(ConnectJobFactory); |
168 }; | 170 }; |
169 | 171 |
170 ClientSocketPoolBaseHelper( | 172 ClientSocketPoolBaseHelper( |
171 int max_sockets, | 173 int max_sockets, |
172 int max_sockets_per_group, | 174 int max_sockets_per_group, |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 } | 226 } |
225 | 227 |
226 // Closes all idle sockets if |force| is true. Else, only closes idle | 228 // Closes all idle sockets if |force| is true. Else, only closes idle |
227 // sockets that timed out or can't be reused. Made public for testing. | 229 // sockets that timed out or can't be reused. Made public for testing. |
228 void CleanupIdleSockets(bool force); | 230 void CleanupIdleSockets(bool force); |
229 | 231 |
230 base::TimeDelta ConnectionTimeout() const { | 232 base::TimeDelta ConnectionTimeout() const { |
231 return connect_job_factory_->ConnectionTimeout(); | 233 return connect_job_factory_->ConnectionTimeout(); |
232 } | 234 } |
233 | 235 |
234 void enable_backup_jobs() { backup_jobs_enabled_ = true; }; | 236 void enable_backup_jobs() { backup_jobs_enabled_ = true; } |
235 | 237 |
236 private: | 238 private: |
237 friend class base::RefCounted<ClientSocketPoolBaseHelper>; | 239 friend class base::RefCounted<ClientSocketPoolBaseHelper>; |
238 | 240 |
239 ~ClientSocketPoolBaseHelper(); | 241 ~ClientSocketPoolBaseHelper(); |
240 | 242 |
241 // Entry for a persistent socket which became idle at time |start_time|. | 243 // Entry for a persistent socket which became idle at time |start_time|. |
242 struct IdleSocket { | 244 struct IdleSocket { |
243 IdleSocket() : socket(NULL), used(false) {} | 245 IdleSocket() : socket(NULL), used(false) {} |
244 ClientSocket* socket; | 246 ClientSocket* socket; |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 // Returns true if we can't create any more sockets due to the total limit. | 382 // Returns true if we can't create any more sockets due to the total limit. |
381 // TODO(phajdan.jr): Also take idle sockets into account. | 383 // TODO(phajdan.jr): Also take idle sockets into account. |
382 bool ReachedMaxSocketsLimit() const; | 384 bool ReachedMaxSocketsLimit() const; |
383 | 385 |
384 // This is the internal implementation of RequestSocket(). It differs in that | 386 // This is the internal implementation of RequestSocket(). It differs in that |
385 // it does not handle logging into NetLog of the queueing status of | 387 // it does not handle logging into NetLog of the queueing status of |
386 // |request|. | 388 // |request|. |
387 int RequestSocketInternal(const std::string& group_name, | 389 int RequestSocketInternal(const std::string& group_name, |
388 const Request* request); | 390 const Request* request); |
389 | 391 |
| 392 static void LogBoundConnectJobToRequest( |
| 393 const NetLog::Source& connect_job_source, const Request* request); |
| 394 |
390 // Set a timer to create a backup socket if it takes too long to create one. | 395 // Set a timer to create a backup socket if it takes too long to create one. |
391 void StartBackupSocketTimer(const std::string& group_name); | 396 void StartBackupSocketTimer(const std::string& group_name); |
392 | 397 |
393 // Called when the backup socket timer fires. | 398 // Called when the backup socket timer fires. |
394 void OnBackupSocketTimerFired(const std::string& group_name); | 399 void OnBackupSocketTimerFired(const std::string& group_name); |
395 | 400 |
396 GroupMap group_map_; | 401 GroupMap group_map_; |
397 | 402 |
398 // Timer used to periodically prune idle sockets that timed out or can't be | 403 // Timer used to periodically prune idle sockets that timed out or can't be |
399 // reused. | 404 // reused. |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 }; | 484 }; |
480 | 485 |
481 class ConnectJobFactory { | 486 class ConnectJobFactory { |
482 public: | 487 public: |
483 ConnectJobFactory() {} | 488 ConnectJobFactory() {} |
484 virtual ~ConnectJobFactory() {} | 489 virtual ~ConnectJobFactory() {} |
485 | 490 |
486 virtual ConnectJob* NewConnectJob( | 491 virtual ConnectJob* NewConnectJob( |
487 const std::string& group_name, | 492 const std::string& group_name, |
488 const Request& request, | 493 const Request& request, |
489 ConnectJob::Delegate* delegate, | 494 ConnectJob::Delegate* delegate) const = 0; |
490 const BoundNetLog& net_log) const = 0; | |
491 | 495 |
492 virtual base::TimeDelta ConnectionTimeout() const = 0; | 496 virtual base::TimeDelta ConnectionTimeout() const = 0; |
493 | 497 |
494 private: | 498 private: |
495 DISALLOW_COPY_AND_ASSIGN(ConnectJobFactory); | 499 DISALLOW_COPY_AND_ASSIGN(ConnectJobFactory); |
496 }; | 500 }; |
497 | 501 |
498 // |max_sockets| is the maximum number of sockets to be maintained by this | 502 // |max_sockets| is the maximum number of sockets to be maintained by this |
499 // ClientSocketPool. |max_sockets_per_group| specifies the maximum number of | 503 // ClientSocketPool. |max_sockets_per_group| specifies the maximum number of |
500 // sockets a "group" can have. |unused_idle_socket_timeout| specifies how | 504 // sockets a "group" can have. |unused_idle_socket_timeout| specifies how |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 } | 577 } |
574 | 578 |
575 base::TimeDelta ConnectionTimeout() const { | 579 base::TimeDelta ConnectionTimeout() const { |
576 return helper_->ConnectionTimeout(); | 580 return helper_->ConnectionTimeout(); |
577 } | 581 } |
578 | 582 |
579 scoped_refptr<ClientSocketPoolHistograms> histograms() const { | 583 scoped_refptr<ClientSocketPoolHistograms> histograms() const { |
580 return histograms_; | 584 return histograms_; |
581 } | 585 } |
582 | 586 |
583 void enable_backup_jobs() { helper_->enable_backup_jobs(); }; | 587 void enable_backup_jobs() { helper_->enable_backup_jobs(); } |
584 | 588 |
585 private: | 589 private: |
586 // This adaptor class exists to bridge the | 590 // This adaptor class exists to bridge the |
587 // internal::ClientSocketPoolBaseHelper::ConnectJobFactory and | 591 // internal::ClientSocketPoolBaseHelper::ConnectJobFactory and |
588 // ClientSocketPoolBase::ConnectJobFactory types, allowing clients to use the | 592 // ClientSocketPoolBase::ConnectJobFactory types, allowing clients to use the |
589 // typesafe ClientSocketPoolBase::ConnectJobFactory, rather than having to | 593 // typesafe ClientSocketPoolBase::ConnectJobFactory, rather than having to |
590 // static_cast themselves. | 594 // static_cast themselves. |
591 class ConnectJobFactoryAdaptor | 595 class ConnectJobFactoryAdaptor |
592 : public internal::ClientSocketPoolBaseHelper::ConnectJobFactory { | 596 : public internal::ClientSocketPoolBaseHelper::ConnectJobFactory { |
593 public: | 597 public: |
594 typedef typename ClientSocketPoolBase<SocketParams>::ConnectJobFactory | 598 typedef typename ClientSocketPoolBase<SocketParams>::ConnectJobFactory |
595 ConnectJobFactory; | 599 ConnectJobFactory; |
596 | 600 |
597 explicit ConnectJobFactoryAdaptor( | 601 explicit ConnectJobFactoryAdaptor( |
598 ConnectJobFactory* connect_job_factory) | 602 ConnectJobFactory* connect_job_factory) |
599 : connect_job_factory_(connect_job_factory) {} | 603 : connect_job_factory_(connect_job_factory) {} |
600 virtual ~ConnectJobFactoryAdaptor() {} | 604 virtual ~ConnectJobFactoryAdaptor() {} |
601 | 605 |
602 virtual ConnectJob* NewConnectJob( | 606 virtual ConnectJob* NewConnectJob( |
603 const std::string& group_name, | 607 const std::string& group_name, |
604 const internal::ClientSocketPoolBaseHelper::Request& request, | 608 const internal::ClientSocketPoolBaseHelper::Request& request, |
605 ConnectJob::Delegate* delegate, | 609 ConnectJob::Delegate* delegate) const { |
606 const BoundNetLog& net_log) const { | |
607 const Request* casted_request = static_cast<const Request*>(&request); | 610 const Request* casted_request = static_cast<const Request*>(&request); |
608 return connect_job_factory_->NewConnectJob( | 611 return connect_job_factory_->NewConnectJob( |
609 group_name, *casted_request, delegate, net_log); | 612 group_name, *casted_request, delegate); |
610 } | 613 } |
611 | 614 |
612 virtual base::TimeDelta ConnectionTimeout() const { | 615 virtual base::TimeDelta ConnectionTimeout() const { |
613 return connect_job_factory_->ConnectionTimeout(); | 616 return connect_job_factory_->ConnectionTimeout(); |
614 } | 617 } |
615 | 618 |
616 const scoped_ptr<ConnectJobFactory> connect_job_factory_; | 619 const scoped_ptr<ConnectJobFactory> connect_job_factory_; |
617 }; | 620 }; |
618 | 621 |
619 // Histograms for the pool | 622 // Histograms for the pool |
620 const scoped_refptr<ClientSocketPoolHistograms> histograms_; | 623 const scoped_refptr<ClientSocketPoolHistograms> histograms_; |
621 | 624 |
622 // One might ask why ClientSocketPoolBaseHelper is also refcounted if its | 625 // One might ask why ClientSocketPoolBaseHelper is also refcounted if its |
623 // containing ClientSocketPool is already refcounted. The reason is because | 626 // containing ClientSocketPool is already refcounted. The reason is because |
624 // DoReleaseSocket() posts a task. If ClientSocketPool gets deleted between | 627 // DoReleaseSocket() posts a task. If ClientSocketPool gets deleted between |
625 // the posting of the task and the execution, then we'll hit the DCHECK that | 628 // the posting of the task and the execution, then we'll hit the DCHECK that |
626 // |ClientSocketPoolBaseHelper::group_map_| is empty. | 629 // |ClientSocketPoolBaseHelper::group_map_| is empty. |
627 scoped_refptr<internal::ClientSocketPoolBaseHelper> helper_; | 630 scoped_refptr<internal::ClientSocketPoolBaseHelper> helper_; |
628 | 631 |
629 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); | 632 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); |
630 }; | 633 }; |
631 | 634 |
632 } // namespace net | 635 } // namespace net |
633 | 636 |
634 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ | 637 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ |
OLD | NEW |