OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 ConnectJob* job) = 0; | 74 ConnectJob* job) = 0; |
75 | 75 |
76 private: | 76 private: |
77 DISALLOW_COPY_AND_ASSIGN(Delegate); | 77 DISALLOW_COPY_AND_ASSIGN(Delegate); |
78 }; | 78 }; |
79 | 79 |
80 // A |timeout_duration| of 0 corresponds to no timeout. | 80 // A |timeout_duration| of 0 corresponds to no timeout. |
81 ConnectJob(const std::string& group_name, | 81 ConnectJob(const std::string& group_name, |
82 base::TimeDelta timeout_duration, | 82 base::TimeDelta timeout_duration, |
83 RequestPriority priority, | 83 RequestPriority priority, |
| 84 ClientSocketPool::RespectLimits respect_limits, |
84 Delegate* delegate, | 85 Delegate* delegate, |
85 const BoundNetLog& net_log); | 86 const BoundNetLog& net_log); |
86 virtual ~ConnectJob(); | 87 virtual ~ConnectJob(); |
87 | 88 |
88 // Accessors | 89 // Accessors |
89 const std::string& group_name() const { return group_name_; } | 90 const std::string& group_name() const { return group_name_; } |
90 const BoundNetLog& net_log() { return net_log_; } | 91 const BoundNetLog& net_log() { return net_log_; } |
91 | 92 |
92 // Releases ownership of the underlying socket to the caller. | 93 // Releases ownership of the underlying socket to the caller. |
93 // Returns the released socket, or NULL if there was a connection | 94 // Returns the released socket, or NULL if there was a connection |
(...skipping 16 matching lines...) Expand all Loading... |
110 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {} | 111 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {} |
111 | 112 |
112 const LoadTimingInfo::ConnectTiming& connect_timing() const { | 113 const LoadTimingInfo::ConnectTiming& connect_timing() const { |
113 return connect_timing_; | 114 return connect_timing_; |
114 } | 115 } |
115 | 116 |
116 const BoundNetLog& net_log() const { return net_log_; } | 117 const BoundNetLog& net_log() const { return net_log_; } |
117 | 118 |
118 protected: | 119 protected: |
119 RequestPriority priority() const { return priority_; } | 120 RequestPriority priority() const { return priority_; } |
| 121 ClientSocketPool::RespectLimits respect_limits() const { |
| 122 return respect_limits_; |
| 123 } |
120 void SetSocket(scoped_ptr<StreamSocket> socket); | 124 void SetSocket(scoped_ptr<StreamSocket> socket); |
121 StreamSocket* socket() { return socket_.get(); } | 125 StreamSocket* socket() { return socket_.get(); } |
122 void NotifyDelegateOfCompletion(int rv); | 126 void NotifyDelegateOfCompletion(int rv); |
123 void ResetTimer(base::TimeDelta remainingTime); | 127 void ResetTimer(base::TimeDelta remainingTime); |
124 | 128 |
125 // Connection establishment timing information. | 129 // Connection establishment timing information. |
126 LoadTimingInfo::ConnectTiming connect_timing_; | 130 LoadTimingInfo::ConnectTiming connect_timing_; |
127 | 131 |
128 private: | 132 private: |
129 virtual int ConnectInternal() = 0; | 133 virtual int ConnectInternal() = 0; |
130 | 134 |
131 void LogConnectStart(); | 135 void LogConnectStart(); |
132 void LogConnectCompletion(int net_error); | 136 void LogConnectCompletion(int net_error); |
133 | 137 |
134 // Alerts the delegate that the ConnectJob has timed out. | 138 // Alerts the delegate that the ConnectJob has timed out. |
135 void OnTimeout(); | 139 void OnTimeout(); |
136 | 140 |
137 const std::string group_name_; | 141 const std::string group_name_; |
138 const base::TimeDelta timeout_duration_; | 142 const base::TimeDelta timeout_duration_; |
139 // TODO(akalin): Support reprioritization. | 143 // TODO(akalin): Support reprioritization. |
140 const RequestPriority priority_; | 144 const RequestPriority priority_; |
| 145 const ClientSocketPool::RespectLimits respect_limits_; |
141 // Timer to abort jobs that take too long. | 146 // Timer to abort jobs that take too long. |
142 base::OneShotTimer timer_; | 147 base::OneShotTimer timer_; |
143 Delegate* delegate_; | 148 Delegate* delegate_; |
144 scoped_ptr<StreamSocket> socket_; | 149 scoped_ptr<StreamSocket> socket_; |
145 BoundNetLog net_log_; | 150 BoundNetLog net_log_; |
146 // A ConnectJob is idle until Connect() has been called. | 151 // A ConnectJob is idle until Connect() has been called. |
147 bool idle_; | 152 bool idle_; |
148 | 153 |
149 DISALLOW_COPY_AND_ASSIGN(ConnectJob); | 154 DISALLOW_COPY_AND_ASSIGN(ConnectJob); |
150 }; | 155 }; |
(...skipping 15 matching lines...) Expand all Loading... |
166 enum Flag { | 171 enum Flag { |
167 NORMAL = 0, // Normal behavior. | 172 NORMAL = 0, // Normal behavior. |
168 NO_IDLE_SOCKETS = 0x1, // Do not return an idle socket. Create a new one. | 173 NO_IDLE_SOCKETS = 0x1, // Do not return an idle socket. Create a new one. |
169 }; | 174 }; |
170 | 175 |
171 class NET_EXPORT_PRIVATE Request { | 176 class NET_EXPORT_PRIVATE Request { |
172 public: | 177 public: |
173 Request(ClientSocketHandle* handle, | 178 Request(ClientSocketHandle* handle, |
174 const CompletionCallback& callback, | 179 const CompletionCallback& callback, |
175 RequestPriority priority, | 180 RequestPriority priority, |
176 bool ignore_limits, | 181 ClientSocketPool::RespectLimits respect_limits, |
177 Flags flags, | 182 Flags flags, |
178 const BoundNetLog& net_log); | 183 const BoundNetLog& net_log); |
179 | 184 |
180 virtual ~Request(); | 185 virtual ~Request(); |
181 | 186 |
182 ClientSocketHandle* handle() const { return handle_; } | 187 ClientSocketHandle* handle() const { return handle_; } |
183 const CompletionCallback& callback() const { return callback_; } | 188 const CompletionCallback& callback() const { return callback_; } |
184 RequestPriority priority() const { return priority_; } | 189 RequestPriority priority() const { return priority_; } |
185 bool ignore_limits() const { return ignore_limits_; } | 190 ClientSocketPool::RespectLimits respect_limits() const { |
| 191 return respect_limits_; |
| 192 } |
186 Flags flags() const { return flags_; } | 193 Flags flags() const { return flags_; } |
187 const BoundNetLog& net_log() const { return net_log_; } | 194 const BoundNetLog& net_log() const { return net_log_; } |
188 | 195 |
189 // TODO(eroman): Temporary until crbug.com/467797 is solved. | 196 // TODO(eroman): Temporary until crbug.com/467797 is solved. |
190 void CrashIfInvalid() const; | 197 void CrashIfInvalid() const; |
191 | 198 |
192 private: | 199 private: |
193 // TODO(eroman): Temporary until crbug.com/467797 is solved. | 200 // TODO(eroman): Temporary until crbug.com/467797 is solved. |
194 enum Liveness { | 201 enum Liveness { |
195 ALIVE = 0xCA11AB13, | 202 ALIVE = 0xCA11AB13, |
196 DEAD = 0xDEADBEEF, | 203 DEAD = 0xDEADBEEF, |
197 }; | 204 }; |
198 | 205 |
199 ClientSocketHandle* const handle_; | 206 ClientSocketHandle* const handle_; |
200 const CompletionCallback callback_; | 207 const CompletionCallback callback_; |
201 // TODO(akalin): Support reprioritization. | 208 // TODO(akalin): Support reprioritization. |
202 const RequestPriority priority_; | 209 const RequestPriority priority_; |
203 const bool ignore_limits_; | 210 const ClientSocketPool::RespectLimits respect_limits_; |
204 const Flags flags_; | 211 const Flags flags_; |
205 const BoundNetLog net_log_; | 212 const BoundNetLog net_log_; |
206 | 213 |
207 // TODO(eroman): Temporary until crbug.com/467797 is solved. | 214 // TODO(eroman): Temporary until crbug.com/467797 is solved. |
208 Liveness liveness_ = ALIVE; | 215 Liveness liveness_ = ALIVE; |
209 | 216 |
210 DISALLOW_COPY_AND_ASSIGN(Request); | 217 DISALLOW_COPY_AND_ASSIGN(Request); |
211 }; | 218 }; |
212 | 219 |
213 class ConnectJobFactory { | 220 class ConnectJobFactory { |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 | 406 |
400 // Returns true if the group could make use of an additional socket slot, if | 407 // Returns true if the group could make use of an additional socket slot, if |
401 // it were given one. | 408 // it were given one. |
402 bool CanUseAdditionalSocketSlot(int max_sockets_per_group) const { | 409 bool CanUseAdditionalSocketSlot(int max_sockets_per_group) const { |
403 return HasAvailableSocketSlot(max_sockets_per_group) && | 410 return HasAvailableSocketSlot(max_sockets_per_group) && |
404 pending_requests_.size() > jobs_.size(); | 411 pending_requests_.size() > jobs_.size(); |
405 } | 412 } |
406 | 413 |
407 // Returns the priority of the top of the pending request queue | 414 // Returns the priority of the top of the pending request queue |
408 // (which may be less than the maximum priority over the entire | 415 // (which may be less than the maximum priority over the entire |
409 // queue, due to how we prioritize requests with |ignore_limits| | 416 // queue, due to how we prioritize requests with |respect_limits| |
410 // set over others). | 417 // DISABLED over others). |
411 RequestPriority TopPendingPriority() const { | 418 RequestPriority TopPendingPriority() const { |
412 // NOTE: FirstMax().value()->priority() is not the same as | 419 // NOTE: FirstMax().value()->priority() is not the same as |
413 // FirstMax().priority()! | 420 // FirstMax().priority()! |
414 return pending_requests_.FirstMax().value()->priority(); | 421 return pending_requests_.FirstMax().value()->priority(); |
415 } | 422 } |
416 | 423 |
417 // Set a timer to create a backup job if it takes too long to | 424 // Set a timer to create a backup job if it takes too long to |
418 // create one and if a timer isn't already running. | 425 // create one and if a timer isn't already running. |
419 void StartBackupJobTimer(const std::string& group_name, | 426 void StartBackupJobTimer(const std::string& group_name, |
420 ClientSocketPoolBaseHelper* pool); | 427 ClientSocketPoolBaseHelper* pool); |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 } // namespace internal | 680 } // namespace internal |
674 | 681 |
675 template <typename SocketParams> | 682 template <typename SocketParams> |
676 class ClientSocketPoolBase { | 683 class ClientSocketPoolBase { |
677 public: | 684 public: |
678 class Request : public internal::ClientSocketPoolBaseHelper::Request { | 685 class Request : public internal::ClientSocketPoolBaseHelper::Request { |
679 public: | 686 public: |
680 Request(ClientSocketHandle* handle, | 687 Request(ClientSocketHandle* handle, |
681 const CompletionCallback& callback, | 688 const CompletionCallback& callback, |
682 RequestPriority priority, | 689 RequestPriority priority, |
| 690 ClientSocketPool::RespectLimits respect_limits, |
683 internal::ClientSocketPoolBaseHelper::Flags flags, | 691 internal::ClientSocketPoolBaseHelper::Flags flags, |
684 bool ignore_limits, | |
685 const scoped_refptr<SocketParams>& params, | 692 const scoped_refptr<SocketParams>& params, |
686 const BoundNetLog& net_log) | 693 const BoundNetLog& net_log) |
687 : internal::ClientSocketPoolBaseHelper::Request( | 694 : internal::ClientSocketPoolBaseHelper::Request(handle, |
688 handle, callback, priority, ignore_limits, flags, net_log), | 695 callback, |
| 696 priority, |
| 697 respect_limits, |
| 698 flags, |
| 699 net_log), |
689 params_(params) {} | 700 params_(params) {} |
690 | 701 |
691 const scoped_refptr<SocketParams>& params() const { return params_; } | 702 const scoped_refptr<SocketParams>& params() const { return params_; } |
692 | 703 |
693 private: | 704 private: |
694 const scoped_refptr<SocketParams> params_; | 705 const scoped_refptr<SocketParams> params_; |
695 }; | 706 }; |
696 | 707 |
697 class ConnectJobFactory { | 708 class ConnectJobFactory { |
698 public: | 709 public: |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 | 753 |
743 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) { | 754 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) { |
744 helper_.RemoveHigherLayeredPool(higher_pool); | 755 helper_.RemoveHigherLayeredPool(higher_pool); |
745 } | 756 } |
746 | 757 |
747 // RequestSocket bundles up the parameters into a Request and then forwards to | 758 // RequestSocket bundles up the parameters into a Request and then forwards to |
748 // ClientSocketPoolBaseHelper::RequestSocket(). | 759 // ClientSocketPoolBaseHelper::RequestSocket(). |
749 int RequestSocket(const std::string& group_name, | 760 int RequestSocket(const std::string& group_name, |
750 const scoped_refptr<SocketParams>& params, | 761 const scoped_refptr<SocketParams>& params, |
751 RequestPriority priority, | 762 RequestPriority priority, |
| 763 ClientSocketPool::RespectLimits respect_limits, |
752 ClientSocketHandle* handle, | 764 ClientSocketHandle* handle, |
753 const CompletionCallback& callback, | 765 const CompletionCallback& callback, |
754 const BoundNetLog& net_log) { | 766 const BoundNetLog& net_log) { |
755 scoped_ptr<const Request> request( | 767 scoped_ptr<const Request> request(new Request( |
756 new Request(handle, callback, priority, | 768 handle, callback, priority, respect_limits, |
757 internal::ClientSocketPoolBaseHelper::NORMAL, | 769 internal::ClientSocketPoolBaseHelper::NORMAL, params, net_log)); |
758 params->ignore_limits(), | |
759 params, net_log)); | |
760 return helper_.RequestSocket(group_name, std::move(request)); | 770 return helper_.RequestSocket(group_name, std::move(request)); |
761 } | 771 } |
762 | 772 |
763 // RequestSockets bundles up the parameters into a Request and then forwards | 773 // RequestSockets bundles up the parameters into a Request and then forwards |
764 // to ClientSocketPoolBaseHelper::RequestSockets(). Note that it assigns the | 774 // to ClientSocketPoolBaseHelper::RequestSockets(). Note that it assigns the |
765 // priority to IDLE and specifies the NO_IDLE_SOCKETS flag. | 775 // priority to IDLE and specifies the NO_IDLE_SOCKETS flag. |
766 void RequestSockets(const std::string& group_name, | 776 void RequestSockets(const std::string& group_name, |
767 const scoped_refptr<SocketParams>& params, | 777 const scoped_refptr<SocketParams>& params, |
768 int num_sockets, | 778 int num_sockets, |
769 const BoundNetLog& net_log) { | 779 const BoundNetLog& net_log) { |
770 const Request request(NULL /* no handle */, CompletionCallback(), IDLE, | 780 const Request request(nullptr /* no handle */, CompletionCallback(), IDLE, |
| 781 ClientSocketPool::RespectLimits::ENABLED, |
771 internal::ClientSocketPoolBaseHelper::NO_IDLE_SOCKETS, | 782 internal::ClientSocketPoolBaseHelper::NO_IDLE_SOCKETS, |
772 params->ignore_limits(), params, net_log); | 783 params, net_log); |
773 helper_.RequestSockets(group_name, request, num_sockets); | 784 helper_.RequestSockets(group_name, request, num_sockets); |
774 } | 785 } |
775 | 786 |
776 void CancelRequest(const std::string& group_name, | 787 void CancelRequest(const std::string& group_name, |
777 ClientSocketHandle* handle) { | 788 ClientSocketHandle* handle) { |
778 return helper_.CancelRequest(group_name, handle); | 789 return helper_.CancelRequest(group_name, handle); |
779 } | 790 } |
780 | 791 |
781 void ReleaseSocket(const std::string& group_name, | 792 void ReleaseSocket(const std::string& group_name, |
782 scoped_ptr<StreamSocket> socket, | 793 scoped_ptr<StreamSocket> socket, |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
875 }; | 886 }; |
876 | 887 |
877 internal::ClientSocketPoolBaseHelper helper_; | 888 internal::ClientSocketPoolBaseHelper helper_; |
878 | 889 |
879 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); | 890 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); |
880 }; | 891 }; |
881 | 892 |
882 } // namespace net | 893 } // namespace net |
883 | 894 |
884 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ | 895 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ |
OLD | NEW |