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

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

Issue 848006: Generalize the net module's LoadLog facility from a passive container, to an event stream (NetLog). (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Split up RequestTracker into ConnectJobTracker+RequestTracker+RequestTrackerBase, address comments Created 10 years, 9 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_pool.h ('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) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 20 matching lines...) Expand all
31 #include "base/compiler_specific.h" 31 #include "base/compiler_specific.h"
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/network_change_notifier.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 class LoadLog;
50 50
51 // ConnectJob provides an abstract interface for "connecting" a socket. 51 // ConnectJob provides an abstract interface for "connecting" a socket.
52 // The connection may involve host resolution, tcp connection, ssl connection, 52 // The connection may involve host resolution, tcp connection, ssl connection,
53 // etc. 53 // etc.
54 class ConnectJob { 54 class ConnectJob {
55 public: 55 public:
56 class Delegate { 56 class Delegate {
57 public: 57 public:
58 Delegate() {} 58 Delegate() {}
59 virtual ~Delegate() {} 59 virtual ~Delegate() {}
60 60
61 // Alerts the delegate that the connection completed. 61 // Alerts the delegate that the connection completed.
62 virtual void OnConnectJobComplete(int result, ConnectJob* job) = 0; 62 virtual void OnConnectJobComplete(int result, ConnectJob* job) = 0;
63 63
64 private: 64 private:
65 DISALLOW_COPY_AND_ASSIGN(Delegate); 65 DISALLOW_COPY_AND_ASSIGN(Delegate);
66 }; 66 };
67 67
68 // A |timeout_duration| of 0 corresponds to no timeout. 68 // A |timeout_duration| of 0 corresponds to no timeout.
69 ConnectJob(const std::string& group_name, 69 ConnectJob(const std::string& group_name,
70 base::TimeDelta timeout_duration, 70 base::TimeDelta timeout_duration,
71 Delegate* delegate, 71 Delegate* delegate,
72 LoadLog* load_log); 72 const BoundNetLog& net_log);
73 virtual ~ConnectJob(); 73 virtual ~ConnectJob();
74 74
75 // Accessors 75 // Accessors
76 const std::string& group_name() const { return group_name_; } 76 const std::string& group_name() const { return group_name_; }
77 LoadLog* load_log() { return load_log_; } 77 const BoundNetLog& net_log() { return net_log_; }
78 78
79 // Releases |socket_| to the client. On connection error, this should return 79 // Releases |socket_| to the client. On connection error, this should return
80 // NULL. 80 // NULL.
81 ClientSocket* ReleaseSocket() { return socket_.release(); } 81 ClientSocket* ReleaseSocket() { return socket_.release(); }
82 82
83 // Begins connecting the socket. Returns OK on success, ERR_IO_PENDING if it 83 // Begins connecting the socket. Returns OK on success, ERR_IO_PENDING if it
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
(...skipping 12 matching lines...) Expand all
100 100
101 // Alerts the delegate that the ConnectJob has timed out. 101 // Alerts the delegate that the ConnectJob has timed out.
102 void OnTimeout(); 102 void OnTimeout();
103 103
104 const std::string group_name_; 104 const std::string group_name_;
105 const base::TimeDelta timeout_duration_; 105 const base::TimeDelta timeout_duration_;
106 // Timer to abort jobs that take too long. 106 // Timer to abort jobs that take too long.
107 base::OneShotTimer<ConnectJob> timer_; 107 base::OneShotTimer<ConnectJob> timer_;
108 Delegate* delegate_; 108 Delegate* delegate_;
109 scoped_ptr<ClientSocket> socket_; 109 scoped_ptr<ClientSocket> socket_;
110 scoped_refptr<LoadLog> load_log_; 110 BoundNetLog net_log_;
111 111
112 DISALLOW_COPY_AND_ASSIGN(ConnectJob); 112 DISALLOW_COPY_AND_ASSIGN(ConnectJob);
113 }; 113 };
114 114
115 namespace internal { 115 namespace internal {
116 116
117 // ClientSocketPoolBaseHelper is an internal class that implements almost all 117 // ClientSocketPoolBaseHelper is an internal class that implements almost all
118 // the functionality from ClientSocketPoolBase without using templates. 118 // the functionality from ClientSocketPoolBase without using templates.
119 // ClientSocketPoolBase adds templated definitions built on top of 119 // ClientSocketPoolBase adds templated definitions built on top of
120 // ClientSocketPoolBaseHelper. This class is not for external use, please use 120 // ClientSocketPoolBaseHelper. This class is not for external use, please use
121 // ClientSocketPoolBase instead. 121 // ClientSocketPoolBase instead.
122 class ClientSocketPoolBaseHelper 122 class ClientSocketPoolBaseHelper
123 : public base::RefCounted<ClientSocketPoolBaseHelper>, 123 : public base::RefCounted<ClientSocketPoolBaseHelper>,
124 public ConnectJob::Delegate, 124 public ConnectJob::Delegate,
125 public NetworkChangeNotifier::Observer { 125 public NetworkChangeNotifier::Observer {
126 public: 126 public:
127 class Request { 127 class Request {
128 public: 128 public:
129 Request(ClientSocketHandle* handle, 129 Request(ClientSocketHandle* handle,
130 CompletionCallback* callback, 130 CompletionCallback* callback,
131 RequestPriority priority, 131 RequestPriority priority,
132 LoadLog* load_log); 132 const BoundNetLog& net_log);
133 133
134 virtual ~Request(); 134 virtual ~Request();
135 135
136 ClientSocketHandle* handle() const { return handle_; } 136 ClientSocketHandle* handle() const { return handle_; }
137 CompletionCallback* callback() const { return callback_; } 137 CompletionCallback* callback() const { return callback_; }
138 RequestPriority priority() const { return priority_; } 138 RequestPriority priority() const { return priority_; }
139 LoadLog* load_log() const { return load_log_.get(); } 139 const BoundNetLog& net_log() const { return net_log_; }
140 140
141 private: 141 private:
142 ClientSocketHandle* const handle_; 142 ClientSocketHandle* const handle_;
143 CompletionCallback* const callback_; 143 CompletionCallback* const callback_;
144 const RequestPriority priority_; 144 const RequestPriority priority_;
145 const scoped_refptr<LoadLog> load_log_; 145 BoundNetLog net_log_;
146 146
147 DISALLOW_COPY_AND_ASSIGN(Request); 147 DISALLOW_COPY_AND_ASSIGN(Request);
148 }; 148 };
149 149
150 class ConnectJobFactory { 150 class ConnectJobFactory {
151 public: 151 public:
152 ConnectJobFactory() {} 152 ConnectJobFactory() {}
153 virtual ~ConnectJobFactory() {} 153 virtual ~ConnectJobFactory() {}
154 154
155 virtual ConnectJob* NewConnectJob( 155 virtual ConnectJob* NewConnectJob(
156 const std::string& group_name, 156 const std::string& group_name,
157 const Request& request, 157 const Request& request,
158 ConnectJob::Delegate* delegate, 158 ConnectJob::Delegate* delegate,
159 LoadLog* load_log) const = 0; 159 const BoundNetLog& net_log) const = 0;
160 160
161 private: 161 private:
162 DISALLOW_COPY_AND_ASSIGN(ConnectJobFactory); 162 DISALLOW_COPY_AND_ASSIGN(ConnectJobFactory);
163 }; 163 };
164 164
165 ClientSocketPoolBaseHelper( 165 ClientSocketPoolBaseHelper(
166 int max_sockets, 166 int max_sockets,
167 int max_sockets_per_group, 167 int max_sockets_per_group,
168 base::TimeDelta unused_idle_socket_timeout, 168 base::TimeDelta unused_idle_socket_timeout,
169 base::TimeDelta used_idle_socket_timeout, 169 base::TimeDelta used_idle_socket_timeout,
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 348
349 // Process a request from a group's pending_requests queue. 349 // Process a request from a group's pending_requests queue.
350 void ProcessPendingRequest(const std::string& group_name, Group* group); 350 void ProcessPendingRequest(const std::string& group_name, Group* group);
351 351
352 // Assigns |socket| to |handle| and updates |group|'s counters appropriately. 352 // Assigns |socket| to |handle| and updates |group|'s counters appropriately.
353 void HandOutSocket(ClientSocket* socket, 353 void HandOutSocket(ClientSocket* socket,
354 bool reused, 354 bool reused,
355 ClientSocketHandle* handle, 355 ClientSocketHandle* handle,
356 base::TimeDelta time_idle, 356 base::TimeDelta time_idle,
357 Group* group, 357 Group* group,
358 LoadLog* load_log); 358 const BoundNetLog& net_log);
359 359
360 // Adds |socket| to the list of idle sockets for |group|. |used| indicates 360 // Adds |socket| to the list of idle sockets for |group|. |used| indicates
361 // whether or not the socket has previously been used. 361 // whether or not the socket has previously been used.
362 void AddIdleSocket(ClientSocket* socket, bool used, Group* group); 362 void AddIdleSocket(ClientSocket* socket, bool used, Group* group);
363 363
364 // Iterates through |connect_job_map_|, canceling all ConnectJobs. 364 // Iterates through |connect_job_map_|, canceling all ConnectJobs.
365 // Afterwards, it iterates through all groups and deletes them if they are no 365 // Afterwards, it iterates through all groups and deletes them if they are no
366 // longer needed. 366 // longer needed.
367 void CancelAllConnectJobs(); 367 void CancelAllConnectJobs();
368 368
369 // Returns true if we can't create any more sockets due to the total limit. 369 // Returns true if we can't create any more sockets due to the total limit.
370 // TODO(phajdan.jr): Also take idle sockets into account. 370 // TODO(phajdan.jr): Also take idle sockets into account.
371 bool ReachedMaxSocketsLimit() const; 371 bool ReachedMaxSocketsLimit() const;
372 372
373 // This is the internal implementation of RequestSocket(). It differs in that 373 // This is the internal implementation of RequestSocket(). It differs in that
374 // it does not handle logging into LoadLog of the queueing status of 374 // it does not handle logging into NetLog of the queueing status of
375 // |request|. 375 // |request|.
376 int RequestSocketInternal(const std::string& group_name, 376 int RequestSocketInternal(const std::string& group_name,
377 const Request* request); 377 const Request* request);
378 378
379 // Set a timer to create a backup socket if it takes too long to create one. 379 // Set a timer to create a backup socket if it takes too long to create one.
380 void StartBackupSocketTimer(const std::string& group_name); 380 void StartBackupSocketTimer(const std::string& group_name);
381 381
382 // Called when the backup socket timer fires. 382 // Called when the backup socket timer fires.
383 void OnBackupSocketTimerFired(const std::string& group_name); 383 void OnBackupSocketTimerFired(const std::string& group_name);
384 384
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 443
444 template <typename SocketParams> 444 template <typename SocketParams>
445 class ClientSocketPoolBase { 445 class ClientSocketPoolBase {
446 public: 446 public:
447 class Request : public internal::ClientSocketPoolBaseHelper::Request { 447 class Request : public internal::ClientSocketPoolBaseHelper::Request {
448 public: 448 public:
449 Request(ClientSocketHandle* handle, 449 Request(ClientSocketHandle* handle,
450 CompletionCallback* callback, 450 CompletionCallback* callback,
451 RequestPriority priority, 451 RequestPriority priority,
452 const SocketParams& params, 452 const SocketParams& params,
453 LoadLog* load_log) 453 const BoundNetLog& net_log)
454 : internal::ClientSocketPoolBaseHelper::Request( 454 : internal::ClientSocketPoolBaseHelper::Request(
455 handle, callback, priority, load_log), 455 handle, callback, priority, net_log),
456 params_(params) {} 456 params_(params) {}
457 457
458 const SocketParams& params() const { return params_; } 458 const SocketParams& params() const { return params_; }
459 459
460 private: 460 private:
461 SocketParams params_; 461 SocketParams params_;
462 }; 462 };
463 463
464 class ConnectJobFactory { 464 class ConnectJobFactory {
465 public: 465 public:
466 ConnectJobFactory() {} 466 ConnectJobFactory() {}
467 virtual ~ConnectJobFactory() {} 467 virtual ~ConnectJobFactory() {}
468 468
469 virtual ConnectJob* NewConnectJob( 469 virtual ConnectJob* NewConnectJob(
470 const std::string& group_name, 470 const std::string& group_name,
471 const Request& request, 471 const Request& request,
472 ConnectJob::Delegate* delegate, 472 ConnectJob::Delegate* delegate,
473 LoadLog* load_log) const = 0; 473 const BoundNetLog& net_log) const = 0;
474 474
475 private: 475 private:
476 DISALLOW_COPY_AND_ASSIGN(ConnectJobFactory); 476 DISALLOW_COPY_AND_ASSIGN(ConnectJobFactory);
477 }; 477 };
478 478
479 // |max_sockets| is the maximum number of sockets to be maintained by this 479 // |max_sockets| is the maximum number of sockets to be maintained by this
480 // ClientSocketPool. |max_sockets_per_group| specifies the maximum number of 480 // ClientSocketPool. |max_sockets_per_group| specifies the maximum number of
481 // sockets a "group" can have. |unused_idle_socket_timeout| specifies how 481 // sockets a "group" can have. |unused_idle_socket_timeout| specifies how
482 // long to leave an unused idle socket open before closing it. 482 // long to leave an unused idle socket open before closing it.
483 // |used_idle_socket_timeout| specifies how long to leave a previously used 483 // |used_idle_socket_timeout| specifies how long to leave a previously used
(...skipping 16 matching lines...) Expand all
500 // These member functions simply forward to ClientSocketPoolBaseHelper. 500 // These member functions simply forward to ClientSocketPoolBaseHelper.
501 501
502 // RequestSocket bundles up the parameters into a Request and then forwards to 502 // RequestSocket bundles up the parameters into a Request and then forwards to
503 // ClientSocketPoolBaseHelper::RequestSocket(). Note that the memory 503 // ClientSocketPoolBaseHelper::RequestSocket(). Note that the memory
504 // ownership is transferred in the asynchronous (ERR_IO_PENDING) case. 504 // ownership is transferred in the asynchronous (ERR_IO_PENDING) case.
505 int RequestSocket(const std::string& group_name, 505 int RequestSocket(const std::string& group_name,
506 const SocketParams& params, 506 const SocketParams& params,
507 RequestPriority priority, 507 RequestPriority priority,
508 ClientSocketHandle* handle, 508 ClientSocketHandle* handle,
509 CompletionCallback* callback, 509 CompletionCallback* callback,
510 LoadLog* load_log) { 510 const BoundNetLog& net_log) {
511 scoped_ptr<Request> request( 511 scoped_ptr<Request> request(
512 new Request(handle, callback, priority, params, load_log)); 512 new Request(handle, callback, priority, params, net_log));
513 int rv = helper_->RequestSocket(group_name, request.get()); 513 int rv = helper_->RequestSocket(group_name, request.get());
514 if (rv == ERR_IO_PENDING) 514 if (rv == ERR_IO_PENDING)
515 request.release(); 515 request.release();
516 return rv; 516 return rv;
517 } 517 }
518 518
519 void CancelRequest(const std::string& group_name, 519 void CancelRequest(const std::string& group_name,
520 const ClientSocketHandle* handle) { 520 const ClientSocketHandle* handle) {
521 return helper_->CancelRequest(group_name, handle); 521 return helper_->CancelRequest(group_name, handle);
522 } 522 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 569
570 explicit ConnectJobFactoryAdaptor( 570 explicit ConnectJobFactoryAdaptor(
571 ConnectJobFactory* connect_job_factory) 571 ConnectJobFactory* connect_job_factory)
572 : connect_job_factory_(connect_job_factory) {} 572 : connect_job_factory_(connect_job_factory) {}
573 virtual ~ConnectJobFactoryAdaptor() {} 573 virtual ~ConnectJobFactoryAdaptor() {}
574 574
575 virtual ConnectJob* NewConnectJob( 575 virtual ConnectJob* NewConnectJob(
576 const std::string& group_name, 576 const std::string& group_name,
577 const internal::ClientSocketPoolBaseHelper::Request& request, 577 const internal::ClientSocketPoolBaseHelper::Request& request,
578 ConnectJob::Delegate* delegate, 578 ConnectJob::Delegate* delegate,
579 LoadLog* load_log) const { 579 const BoundNetLog& net_log) const {
580 const Request* casted_request = static_cast<const Request*>(&request); 580 const Request* casted_request = static_cast<const Request*>(&request);
581 return connect_job_factory_->NewConnectJob( 581 return connect_job_factory_->NewConnectJob(
582 group_name, *casted_request, delegate, load_log); 582 group_name, *casted_request, delegate, net_log);
583 } 583 }
584 584
585 const scoped_ptr<ConnectJobFactory> connect_job_factory_; 585 const scoped_ptr<ConnectJobFactory> connect_job_factory_;
586 }; 586 };
587 587
588 // One might ask why ClientSocketPoolBaseHelper is also refcounted if its 588 // One might ask why ClientSocketPoolBaseHelper is also refcounted if its
589 // containing ClientSocketPool is already refcounted. The reason is because 589 // containing ClientSocketPool is already refcounted. The reason is because
590 // DoReleaseSocket() posts a task. If ClientSocketPool gets deleted between 590 // DoReleaseSocket() posts a task. If ClientSocketPool gets deleted between
591 // the posting of the task and the execution, then we'll hit the DCHECK that 591 // the posting of the task and the execution, then we'll hit the DCHECK that
592 // |ClientSocketPoolBaseHelper::group_map_| is empty. 592 // |ClientSocketPoolBaseHelper::group_map_| is empty.
593 scoped_refptr<internal::ClientSocketPoolBaseHelper> helper_; 593 scoped_refptr<internal::ClientSocketPoolBaseHelper> helper_;
594 594
595 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); 595 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase);
596 }; 596 };
597 597
598 } // namespace net 598 } // namespace net
599 599
600 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ 600 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_
OLDNEW
« no previous file with comments | « net/socket/client_socket_pool.h ('k') | net/socket/client_socket_pool_base.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698