Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: net/socket/client_socket_pool_base.h

Issue 3191019: A/B experiment for re-establishing TCP connections (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/socket/client_socket.cc ('k') | net/socket/client_socket_pool_base.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 } 232 }
233 233
234 // Closes all idle sockets if |force| is true. Else, only closes idle 234 // Closes all idle sockets if |force| is true. Else, only closes idle
235 // sockets that timed out or can't be reused. Made public for testing. 235 // sockets that timed out or can't be reused. Made public for testing.
236 void CleanupIdleSockets(bool force); 236 void CleanupIdleSockets(bool force);
237 237
238 base::TimeDelta ConnectionTimeout() const { 238 base::TimeDelta ConnectionTimeout() const {
239 return connect_job_factory_->ConnectionTimeout(); 239 return connect_job_factory_->ConnectionTimeout();
240 } 240 }
241 241
242 void EnableBackupJobs() { backup_jobs_enabled_ = true; } 242 static void set_connect_backup_jobs_enabled(bool enabled);
243 void EnableConnectBackupJobs();
243 244
244 private: 245 private:
245 friend class base::RefCounted<ClientSocketPoolBaseHelper>; 246 friend class base::RefCounted<ClientSocketPoolBaseHelper>;
246 247
247 // Entry for a persistent socket which became idle at time |start_time|. 248 // Entry for a persistent socket which became idle at time |start_time|.
248 struct IdleSocket { 249 struct IdleSocket {
249 IdleSocket() : socket(NULL), used(false) {} 250 IdleSocket() : socket(NULL), used(false) {}
250 ClientSocket* socket; 251 ClientSocket* socket;
251 base::TimeTicks start_time; 252 base::TimeTicks start_time;
252 bool used; // Indicates whether or not the socket has been used yet. 253 bool used; // Indicates whether or not the socket has been used yet.
(...skipping 11 matching lines...) Expand all
264 265
265 typedef std::deque<const Request*> RequestQueue; 266 typedef std::deque<const Request*> RequestQueue;
266 typedef std::map<const ClientSocketHandle*, const Request*> RequestMap; 267 typedef std::map<const ClientSocketHandle*, const Request*> RequestMap;
267 268
268 // A Group is allocated per group_name when there are idle sockets or pending 269 // A Group is allocated per group_name when there are idle sockets or pending
269 // requests. Otherwise, the Group object is removed from the map. 270 // requests. Otherwise, the Group object is removed from the map.
270 // |active_socket_count| tracks the number of sockets held by clients. 271 // |active_socket_count| tracks the number of sockets held by clients.
271 struct Group { 272 struct Group {
272 Group() 273 Group()
273 : active_socket_count(0), 274 : active_socket_count(0),
274 backup_job(NULL), 275 connect_backup_job(NULL),
275 backup_task(NULL) { 276 backup_task(NULL) {
276 } 277 }
277 278
278 ~Group() { 279 ~Group() {
279 CleanupBackupJob(); 280 CleanupBackupJob();
280 } 281 }
281 282
282 bool IsEmpty() const { 283 bool IsEmpty() const {
283 return active_socket_count == 0 && idle_sockets.empty() && jobs.empty() && 284 return active_socket_count == 0 && idle_sockets.empty() && jobs.empty() &&
284 pending_requests.empty(); 285 pending_requests.empty();
285 } 286 }
286 287
287 bool HasAvailableSocketSlot(int max_sockets_per_group) const { 288 bool HasAvailableSocketSlot(int max_sockets_per_group) const {
288 return active_socket_count + static_cast<int>(jobs.size()) < 289 return active_socket_count + static_cast<int>(jobs.size()) <
289 max_sockets_per_group; 290 max_sockets_per_group;
290 } 291 }
291 292
292 bool IsStalled(int max_sockets_per_group) const { 293 bool IsStalled(int max_sockets_per_group) const {
293 return HasAvailableSocketSlot(max_sockets_per_group) && 294 return HasAvailableSocketSlot(max_sockets_per_group) &&
294 pending_requests.size() > jobs.size(); 295 pending_requests.size() > jobs.size();
295 } 296 }
296 297
297 RequestPriority TopPendingPriority() const { 298 RequestPriority TopPendingPriority() const {
298 return pending_requests.front()->priority(); 299 return pending_requests.front()->priority();
299 } 300 }
300 301
301 void CleanupBackupJob() { 302 void CleanupBackupJob() {
302 if (backup_job) { 303 if (connect_backup_job) {
303 delete backup_job; 304 delete connect_backup_job;
304 backup_job = NULL; 305 connect_backup_job = NULL;
305 } 306 }
306 if (backup_task) { 307 if (backup_task) {
307 backup_task->Cancel(); 308 backup_task->Cancel();
308 backup_task = NULL; 309 backup_task = NULL;
309 } 310 }
310 } 311 }
311 312
312 std::deque<IdleSocket> idle_sockets; 313 std::deque<IdleSocket> idle_sockets;
313 std::set<const ConnectJob*> jobs; 314 std::set<const ConnectJob*> jobs;
314 RequestQueue pending_requests; 315 RequestQueue pending_requests;
315 int active_socket_count; // number of active sockets used by clients 316 int active_socket_count; // number of active sockets used by clients
316 // A backup job in case the connect for this group takes too long. 317 // A backup job in case the connect for this group takes too long.
317 ConnectJob* backup_job; 318 ConnectJob* connect_backup_job;
318 CancelableTask* backup_task; 319 CancelableTask* backup_task;
319 }; 320 };
320 321
321 typedef std::map<std::string, Group> GroupMap; 322 typedef std::map<std::string, Group> GroupMap;
322 323
323 typedef std::set<const ConnectJob*> ConnectJobSet; 324 typedef std::set<const ConnectJob*> ConnectJobSet;
324 325
325 struct CallbackResultPair { 326 struct CallbackResultPair {
326 CallbackResultPair() : callback(NULL), result(OK) {} 327 CallbackResultPair() : callback(NULL), result(OK) {}
327 CallbackResultPair(CompletionCallback* callback_in, int result_in) 328 CallbackResultPair(CompletionCallback* callback_in, int result_in)
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 // The maximum number of sockets kept per group. 455 // The maximum number of sockets kept per group.
455 const int max_sockets_per_group_; 456 const int max_sockets_per_group_;
456 457
457 // The time to wait until closing idle sockets. 458 // The time to wait until closing idle sockets.
458 const base::TimeDelta unused_idle_socket_timeout_; 459 const base::TimeDelta unused_idle_socket_timeout_;
459 const base::TimeDelta used_idle_socket_timeout_; 460 const base::TimeDelta used_idle_socket_timeout_;
460 461
461 const scoped_ptr<ConnectJobFactory> connect_job_factory_; 462 const scoped_ptr<ConnectJobFactory> connect_job_factory_;
462 463
463 // TODO(vandebo) Remove when backup jobs move to TCPClientSocketPool 464 // TODO(vandebo) Remove when backup jobs move to TCPClientSocketPool
464 bool backup_jobs_enabled_; 465 bool connect_backup_jobs_enabled_;
465 466
466 // A factory to pin the backup_job tasks. 467 // A factory to pin the backup_job tasks.
467 ScopedRunnableMethodFactory<ClientSocketPoolBaseHelper> method_factory_; 468 ScopedRunnableMethodFactory<ClientSocketPoolBaseHelper> method_factory_;
468 469
469 // A unique id for the pool. It gets incremented every time we Flush() the 470 // A unique id for the pool. It gets incremented every time we Flush() the
470 // pool. This is so that when sockets get released back to the pool, we can 471 // pool. This is so that when sockets get released back to the pool, we can
471 // make sure that they are discarded rather than reused. 472 // make sure that they are discarded rather than reused.
472 int pool_generation_number_; 473 int pool_generation_number_;
473 474
474 // Some parts of this class need to know if the destructor is running. 475 // Some parts of this class need to know if the destructor is running.
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 } 589 }
589 590
590 base::TimeDelta ConnectionTimeout() const { 591 base::TimeDelta ConnectionTimeout() const {
591 return helper_->ConnectionTimeout(); 592 return helper_->ConnectionTimeout();
592 } 593 }
593 594
594 scoped_refptr<ClientSocketPoolHistograms> histograms() const { 595 scoped_refptr<ClientSocketPoolHistograms> histograms() const {
595 return histograms_; 596 return histograms_;
596 } 597 }
597 598
598 void EnableBackupJobs() { helper_->EnableBackupJobs(); } 599 void EnableConnectBackupJobs() { helper_->EnableConnectBackupJobs(); }
599 600
600 void Flush() { helper_->Flush(); } 601 void Flush() { helper_->Flush(); }
601 602
602 private: 603 private:
603 // This adaptor class exists to bridge the 604 // This adaptor class exists to bridge the
604 // internal::ClientSocketPoolBaseHelper::ConnectJobFactory and 605 // internal::ClientSocketPoolBaseHelper::ConnectJobFactory and
605 // ClientSocketPoolBase::ConnectJobFactory types, allowing clients to use the 606 // ClientSocketPoolBase::ConnectJobFactory types, allowing clients to use the
606 // typesafe ClientSocketPoolBase::ConnectJobFactory, rather than having to 607 // typesafe ClientSocketPoolBase::ConnectJobFactory, rather than having to
607 // static_cast themselves. 608 // static_cast themselves.
608 class ConnectJobFactoryAdaptor 609 class ConnectJobFactoryAdaptor
(...skipping 30 matching lines...) Expand all
639 // ClientSocketPoolBase<T> reference to drop to zero. While we're deep 640 // ClientSocketPoolBase<T> reference to drop to zero. While we're deep
640 // in cleanup code, we'll often hold a reference to |self|. 641 // in cleanup code, we'll often hold a reference to |self|.
641 scoped_refptr<internal::ClientSocketPoolBaseHelper> helper_; 642 scoped_refptr<internal::ClientSocketPoolBaseHelper> helper_;
642 643
643 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); 644 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase);
644 }; 645 };
645 646
646 } // namespace net 647 } // namespace net
647 648
648 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ 649 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_
OLDNEW
« no previous file with comments | « net/socket/client_socket.cc ('k') | net/socket/client_socket_pool_base.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698