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

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

Issue 6052006: Proof of concept for tr1-based Task replacement. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/net/base
Patch Set: Examples of replacing CreateFunctor, ScopedRMF, CompletionCallback Created 9 years, 12 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
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 12 matching lines...) Expand all
23 #define NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ 23 #define NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_
24 #pragma once 24 #pragma once
25 25
26 #include <deque> 26 #include <deque>
27 #include <list> 27 #include <list>
28 #include <map> 28 #include <map>
29 #include <set> 29 #include <set>
30 #include <string> 30 #include <string>
31 31
32 #include "base/basictypes.h" 32 #include "base/basictypes.h"
33 #include "base/closure.h"
33 #include "base/ref_counted.h" 34 #include "base/ref_counted.h"
34 #include "base/scoped_ptr.h" 35 #include "base/scoped_ptr.h"
35 #include "base/task.h" 36 #include "base/task.h"
36 #include "base/time.h" 37 #include "base/time.h"
37 #include "base/timer.h" 38 #include "base/timer.h"
38 #include "net/base/address_list.h" 39 #include "net/base/address_list.h"
39 #include "net/base/completion_callback.h" 40 #include "net/base/completion_callback.h"
40 #include "net/base/load_states.h" 41 #include "net/base/load_states.h"
41 #include "net/base/net_errors.h" 42 #include "net/base/net_errors.h"
42 #include "net/base/net_log.h" 43 #include "net/base/net_log.h"
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 : public ConnectJob::Delegate, 159 : public ConnectJob::Delegate,
159 public NetworkChangeNotifier::Observer { 160 public NetworkChangeNotifier::Observer {
160 public: 161 public:
161 // Used to specify specific behavior for the ClientSocketPool. 162 // Used to specify specific behavior for the ClientSocketPool.
162 enum Flag { 163 enum Flag {
163 NORMAL = 0, // Normal behavior. 164 NORMAL = 0, // Normal behavior.
164 NO_IDLE_SOCKETS = 0x1, // Do not return an idle socket. Create a new one. 165 NO_IDLE_SOCKETS = 0x1, // Do not return an idle socket. Create a new one.
165 }; 166 };
166 167
167 typedef uint32 Flags; 168 typedef uint32 Flags;
169 typedef ::std::tr1::function<void(int)> Tr1CompletionCallback;
168 170
169 class Request { 171 class Request {
170 public: 172 public:
171 Request(ClientSocketHandle* handle, 173 Request(ClientSocketHandle* handle,
172 CompletionCallback* callback, 174 Tr1CompletionCallback callback,
173 RequestPriority priority, 175 RequestPriority priority,
174 Flags flags, 176 Flags flags,
175 const BoundNetLog& net_log); 177 const BoundNetLog& net_log);
176 178
177 virtual ~Request(); 179 virtual ~Request();
178 180
179 ClientSocketHandle* handle() const { return handle_; } 181 ClientSocketHandle* handle() const { return handle_; }
180 CompletionCallback* callback() const { return callback_; } 182 Tr1CompletionCallback callback() const { return callback_; }
181 RequestPriority priority() const { return priority_; } 183 RequestPriority priority() const { return priority_; }
182 Flags flags() const { return flags_; } 184 Flags flags() const { return flags_; }
183 const BoundNetLog& net_log() const { return net_log_; } 185 const BoundNetLog& net_log() const { return net_log_; }
184 186
185 private: 187 private:
186 ClientSocketHandle* const handle_; 188 ClientSocketHandle* const handle_;
187 CompletionCallback* const callback_; 189 Tr1CompletionCallback const callback_;
188 const RequestPriority priority_; 190 const RequestPriority priority_;
189 const Flags flags_; 191 const Flags flags_;
190 BoundNetLog net_log_; 192 BoundNetLog net_log_;
191 193
192 DISALLOW_COPY_AND_ASSIGN(Request); 194 DISALLOW_COPY_AND_ASSIGN(Request);
193 }; 195 };
194 196
195 class ConnectJobFactory { 197 class ConnectJobFactory {
196 public: 198 public:
197 ConnectJobFactory() {} 199 ConnectJobFactory() {}
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 341
340 bool IsStalled(int max_sockets_per_group) const { 342 bool IsStalled(int max_sockets_per_group) const {
341 return HasAvailableSocketSlot(max_sockets_per_group) && 343 return HasAvailableSocketSlot(max_sockets_per_group) &&
342 pending_requests_.size() > jobs_.size(); 344 pending_requests_.size() > jobs_.size();
343 } 345 }
344 346
345 RequestPriority TopPendingPriority() const { 347 RequestPriority TopPendingPriority() const {
346 return pending_requests_.front()->priority(); 348 return pending_requests_.front()->priority();
347 } 349 }
348 350
349 bool HasBackupJob() const { return !method_factory_.empty(); } 351 bool HasBackupJob() const { return !closure_canceller_.empty(); }
350 352
351 void CleanupBackupJob() { 353 void CleanupBackupJob() {
352 method_factory_.RevokeAll(); 354 closure_canceller_.RevokeAll();
353 } 355 }
354 356
355 // Set a timer to create a backup socket if it takes too long to create one. 357 // Set a timer to create a backup socket if it takes too long to create one.
356 void StartBackupSocketTimer(const std::string& group_name, 358 void StartBackupSocketTimer(const std::string& group_name,
357 ClientSocketPoolBaseHelper* pool); 359 ClientSocketPoolBaseHelper* pool);
358 360
359 // Searches |jobs_| to see if there's a preconnect ConnectJob, and if so, 361 // Searches |jobs_| to see if there's a preconnect ConnectJob, and if so,
360 // uses it. Returns true on success. Otherwise, returns false. 362 // uses it. Returns true on success. Otherwise, returns false.
361 bool TryToUsePreconnectConnectJob(); 363 bool TryToUsePreconnectConnectJob();
362 364
(...skipping 15 matching lines...) Expand all
378 // Called when the backup socket timer fires. 380 // Called when the backup socket timer fires.
379 void OnBackupSocketTimerFired( 381 void OnBackupSocketTimerFired(
380 std::string group_name, 382 std::string group_name,
381 ClientSocketPoolBaseHelper* pool); 383 ClientSocketPoolBaseHelper* pool);
382 384
383 std::list<IdleSocket> idle_sockets_; 385 std::list<IdleSocket> idle_sockets_;
384 std::set<ConnectJob*> jobs_; 386 std::set<ConnectJob*> jobs_;
385 RequestQueue pending_requests_; 387 RequestQueue pending_requests_;
386 int active_socket_count_; // number of active sockets used by clients 388 int active_socket_count_; // number of active sockets used by clients
387 // A factory to pin the backup_job tasks. 389 // A factory to pin the backup_job tasks.
388 ScopedRunnableMethodFactory<Group> method_factory_; 390 base::ClosureCanceller closure_canceller_;
389 }; 391 };
390 392
391 typedef std::map<std::string, Group*> GroupMap; 393 typedef std::map<std::string, Group*> GroupMap;
392 394
393 typedef std::set<ConnectJob*> ConnectJobSet; 395 typedef std::set<ConnectJob*> ConnectJobSet;
394 396
395 struct CallbackResultPair { 397 struct CallbackResultPair {
396 CallbackResultPair() : callback(NULL), result(OK) {} 398 CallbackResultPair() : callback(NULL), result(OK) {}
397 CallbackResultPair(CompletionCallback* callback_in, int result_in) 399 CallbackResultPair(Tr1CompletionCallback callback_in, int result_in)
398 : callback(callback_in), result(result_in) {} 400 : callback(callback_in), result(result_in) {}
399 401
400 CompletionCallback* callback; 402 Tr1CompletionCallback callback;
401 int result; 403 int result;
402 }; 404 };
403 405
404 typedef std::map<const ClientSocketHandle*, CallbackResultPair> 406 typedef std::map<const ClientSocketHandle*, CallbackResultPair>
405 PendingCallbackMap; 407 PendingCallbackMap;
406 408
407 static void InsertRequestIntoQueue(const Request* r, 409 static void InsertRequestIntoQueue(const Request* r,
408 RequestQueue* pending_requests); 410 RequestQueue* pending_requests);
409 static const Request* RemoveRequestFromQueue(RequestQueue::iterator it, 411 static const Request* RemoveRequestFromQueue(RequestQueue::iterator it,
410 Group* group); 412 Group* group);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 bool CloseOneIdleSocketExceptInGroup(const Group* group); 488 bool CloseOneIdleSocketExceptInGroup(const Group* group);
487 489
488 // Checks if there are stalled socket groups that should be notified 490 // Checks if there are stalled socket groups that should be notified
489 // for possible wakeup. 491 // for possible wakeup.
490 void CheckForStalledSocketGroups(); 492 void CheckForStalledSocketGroups();
491 493
492 // Posts a task to call InvokeUserCallback() on the next iteration through the 494 // Posts a task to call InvokeUserCallback() on the next iteration through the
493 // current message loop. Inserts |callback| into |pending_callback_map_|, 495 // current message loop. Inserts |callback| into |pending_callback_map_|,
494 // keyed by |handle|. 496 // keyed by |handle|.
495 void InvokeUserCallbackLater( 497 void InvokeUserCallbackLater(
496 ClientSocketHandle* handle, CompletionCallback* callback, int rv); 498 ClientSocketHandle* handle, Tr1CompletionCallback callback, int rv);
497 499
498 // Invokes the user callback for |handle|. By the time this task has run, 500 // Invokes the user callback for |handle|. By the time this task has run,
499 // it's possible that the request has been cancelled, so |handle| may not 501 // it's possible that the request has been cancelled, so |handle| may not
500 // exist in |pending_callback_map_|. We look up the callback and result code 502 // exist in |pending_callback_map_|. We look up the callback and result code
501 // in |pending_callback_map_|. 503 // in |pending_callback_map_|.
502 void InvokeUserCallback(ClientSocketHandle* handle); 504 void InvokeUserCallback(ClientSocketHandle* handle);
503 505
504 GroupMap group_map_; 506 GroupMap group_map_;
505 507
506 // Map of the ClientSocketHandles for which we have a pending Task to invoke a 508 // Map of the ClientSocketHandles for which we have a pending Task to invoke a
(...skipping 27 matching lines...) Expand all
534 const scoped_ptr<ConnectJobFactory> connect_job_factory_; 536 const scoped_ptr<ConnectJobFactory> connect_job_factory_;
535 537
536 // TODO(vandebo) Remove when backup jobs move to TCPClientSocketPool 538 // TODO(vandebo) Remove when backup jobs move to TCPClientSocketPool
537 bool connect_backup_jobs_enabled_; 539 bool connect_backup_jobs_enabled_;
538 540
539 // A unique id for the pool. It gets incremented every time we Flush() the 541 // A unique id for the pool. It gets incremented every time we Flush() the
540 // pool. This is so that when sockets get released back to the pool, we can 542 // pool. This is so that when sockets get released back to the pool, we can
541 // make sure that they are discarded rather than reused. 543 // make sure that they are discarded rather than reused.
542 int pool_generation_number_; 544 int pool_generation_number_;
543 545
544 ScopedRunnableMethodFactory<ClientSocketPoolBaseHelper> method_factory_; 546 base::ClosureCanceller closure_canceller_;
545 547
546 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBaseHelper); 548 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBaseHelper);
547 }; 549 };
548 550
549 } // namespace internal 551 } // namespace internal
550 552
551 // The maximum duration, in seconds, to keep used idle persistent sockets alive. 553 // The maximum duration, in seconds, to keep used idle persistent sockets alive.
552 static const int kUsedIdleSocketTimeout = 300; // 5 minutes 554 static const int kUsedIdleSocketTimeout = 300; // 5 minutes
553 555
554 template <typename SocketParams> 556 template <typename SocketParams>
555 class ClientSocketPoolBase { 557 class ClientSocketPoolBase {
556 public: 558 public:
557 class Request : public internal::ClientSocketPoolBaseHelper::Request { 559 class Request : public internal::ClientSocketPoolBaseHelper::Request {
558 public: 560 public:
559 Request(ClientSocketHandle* handle, 561 Request(ClientSocketHandle* handle,
560 CompletionCallback* callback, 562 CompletionCallback* callback,
561 RequestPriority priority, 563 RequestPriority priority,
562 internal::ClientSocketPoolBaseHelper::Flags flags, 564 internal::ClientSocketPoolBaseHelper::Flags flags,
563 const scoped_refptr<SocketParams>& params, 565 const scoped_refptr<SocketParams>& params,
564 const BoundNetLog& net_log) 566 const BoundNetLog& net_log)
567 // Do a hacky type transition from the CompletionCallback to
568 // Tr1CompletionCallback by binding the method. This is complicated
569 // by the fact that the function we're wrapper has overloads which
570 // forces a cast to hint which overload we want to wrap. This should
571 // not be an issue in most of the code since overloads are discouraged
572 // by the style guide.
573 //
574 // Also note that we We don't need to keep a reference to the callback
575 // because the API does not take ownership. One plus of Tr1 callback is
576 // that there is no such ownership ambiguity. But the downside is
577 // refcounting in the callback.
565 : internal::ClientSocketPoolBaseHelper::Request( 578 : internal::ClientSocketPoolBaseHelper::Request(
566 handle, callback, priority, flags, net_log), 579 handle,
580 ::std::tr1::bind<void(CompletionCallback::*)(const int&)>(
581 &CompletionCallback::Run,
582 callback,
583 std::tr1::placeholders::_1),
584 priority,
585 flags, net_log),
567 params_(params) {} 586 params_(params) {}
568 587
569 const scoped_refptr<SocketParams>& params() const { return params_; } 588 const scoped_refptr<SocketParams>& params() const { return params_; }
570 589
571 private: 590 private:
572 const scoped_refptr<SocketParams> params_; 591 const scoped_refptr<SocketParams> params_;
573 }; 592 };
574 593
575 class ConnectJobFactory { 594 class ConnectJobFactory {
576 public: 595 public:
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 // Histograms for the pool 755 // Histograms for the pool
737 ClientSocketPoolHistograms* const histograms_; 756 ClientSocketPoolHistograms* const histograms_;
738 internal::ClientSocketPoolBaseHelper helper_; 757 internal::ClientSocketPoolBaseHelper helper_;
739 758
740 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); 759 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase);
741 }; 760 };
742 761
743 } // namespace net 762 } // namespace net
744 763
745 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ 764 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698